【问题标题】:Is it right to call and use this as a stub or mock?调用并将其用作存根或模拟是否正确?
【发布时间】:2014-10-30 08:57:09
【问题描述】:

我正在为演示应用程序使用手写的假货,但我不确定我是否正确地使用了模拟。下面是我的代码:

[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();
    }

测试替身:

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);
        }
    }
}

第二个测试实例化了 fake 并将其称为 mock,然后它调用 verify 方法。这种做法是对还是错?

【问题讨论】:

    标签: c# unit-testing tdd xunit.net


    【解决方案1】:

    这就是模拟框架的工作原理

    • 你要么对组件之间的交互做出假设(通常通过各种Expect-family 方法完成),然后Verify它们(你的第二个测试)
    • 或者你告诉你的测试替身以某种方式表现StubSetup)因为它在流程中是必要的(你的第一个测试)

    这种方法是正确的,但它正在重新发明轮子。除非您有充分的理由这样做,否则我会花一些时间来学习和使用其中一种模拟框架(想到 MoqFakeItEasy)。

    【讨论】:

    • @peter 如果您对存根和模拟之间的区别感兴趣,那么在经典意义上,您有一个模拟。具有讽刺意味的是,大多数模拟框架(我特别了解 Moq)都有助于创建存根,即使它们称它们为模拟。请参阅martinfowler.com/articles/mocksArentStubs.html 了解这两个术语之间的全面对比。
    • 我知道这些差异。我可以使用框架轻松创建这些
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 2016-03-07
    • 2011-07-24
    相关资源
    最近更新 更多