Problem: I want to test that a method is only callable by another contract.
Example:
// B.sol
contract B {
A _a;
uint256 i;
constructor(A a) {
_a = a;
i = 0;
}
function doSomething() external {
require(address(_a) == msg.sender);
i += 1;
}
}
// A.sol
contract A {
B _b;
constructor(B b) {
_b = b;
}
function callB() external {
_b.doSomething();
}
}
// B.test.ts
// going to simplify some unimportant stuff here
describe('doSomething', () => {
it('should fulfil when called by contract A', async () => {
const mockA = await deployMockContract('A'); // Waffle
const b = await bFactory.deploy();
const signerFromMockA = b.provider.getSigner(mockA.address);
const bAsMockA = b.connect(signerFromMockA);
await expect(bAsMockA.doSomething()).to.have.eventually.fulfilled;
})
it('should reject when called by other address', async () => {
const mockA = await deployMockContract('A'); // Waffle
const b = await bFactory.deploy();
const [, nonOwner] = ethers.getSigners();
const bAsNonOwner = b.connect(nonOwner);
await expect(bAsNonOwner.doSomething()).to.have.eventually.rejected;
})
})
I expect this to pass, but I get "unknown account" AssertionError, suggesting that the contact methods can be only called by the ethers generated signers.
(Please, ignore the constructors' circular dependency on each other. That's not the point of this example.)