简体   繁体   中英

Is it right to call and use this as a stub or mock?

I'm using handwritten fakes for a demo app but I'm not sure I'm using the mock appropriately. Here's my code below:

[Fact]
    public void TransferFund_WithInsufficientAccountBalance_ThrowsException()
    {
        IBankAccountRepository stubRepository = new FakeBankAccountRepository();
        var service = new BankAccountService(stubRepository);

        const int senderAccountNo = 1, receiverAccountNo = 2;
        const decimal amountToTransfer = 400;

        Assert.Throws<Exception>(() => service.TransferFund(senderAccountNo, receiverAccountNo, amountToTransfer));
    }

    [Fact]
    public void TransferFund_WithSufficientAccountBalance_UpdatesAccounts()
    {
        var mockRepository = new FakeBankAccountRepository();
        var service = new BankAccountService(mockRepository);
        const int senderAccountNo = 1, receiverAccountNo = 2;
        const decimal amountToTransfer = 100;

        service.TransferFund(senderAccountNo, receiverAccountNo, amountToTransfer);

        mockRepository.Verify();
    }

Test double:

public class FakeBankAccountRepository : IBankAccountRepository
{
    private List<BankAccount> _list = new List<BankAccount>
    {
        new BankAccount(1, 200),
        new BankAccount(2, 400)
    };

    private int _updateCalled;

    public void Update(BankAccount bankAccount)
    {
        var account = _list.First(a => a.AccountNo == bankAccount.AccountNo);
        account.Balance = bankAccount.Balance;
        _updateCalled++;
    }

    public void Add(BankAccount bankAccount)
    {
        if (_list.FirstOrDefault(a => a.AccountNo == bankAccount.AccountNo) != null)
            throw new Exception("Account exist");

        _list.Add(bankAccount);
    }

    public BankAccount Find(int accountNo)
    {
        return _list.FirstOrDefault(a => a.AccountNo == accountNo);
    }

    public void Verify()
    {
        if (_updateCalled != 2)
        {
            throw new Xunit.Sdk.AssertException("Update called: " + _updateCalled);
        }
    }
}

the second test instantiates the fake and refers to it as mock, then it calls the verify method. Is this approach right or wrong?

That's how mocking frameworks work

  • You either make assumptions about interactions between components (usually done via various Expect -family methods) and later Verify them (your second test)
  • Or you tell your test double to behave in a certain way ( Stub , Setup ) because it's necessary in the flow (your first test)

The approach is correct but it's reinventing the wheel all over again. Unless you have very good reasons to do so, I'd invest some time into learning and using one of mocking frameworks ( Moq or FakeItEasy come to mind).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM