单元测试存根方法

时间:2009-09-29 15:48:29

标签: c# unit-testing rhino-mocks

鉴于此课程:

public class OrderService
{
    public OrderService(IOrderLogger log)
    {
        this.log = log;
    }

    private readonly IOrderLogger log;

    public void PurgeOrder(Order order)
    {
        ...

        var action = new LogAction("foo","bar");
        log.Action(action);
    }
}   

这个测试:

[Fact]
public void PurgeOrder_should_log_action()
{
    var order = new Order();
    var logger = MockRepository.GenerateStub<IOrderLogger>();
    var service = new OrderService(logger);

    service.PurgeOrder(order);

    logger.AssertWasCalled(x => x.Action(????));
}   

显然测试是错误的。如何在这种情况下断言OrderLogger.Action(...)?如果LogAction在PurgeOrder方法中实例化,我看不出它是如何可能的。有什么建议吗?

3 个答案:

答案 0 :(得分:1)

您需要一些方法来比较LogActions。您可以在LogAction上实现Equals(如果从程序逻辑的角度来看是有意义的话),或者将比较器作为测试的一部分来实现。在第一种情况下,您将创建与生产代码中相同的LogAction。

答案 1 :(得分:1)

[免责声明我的工作是Typemock]

据我所知,唯一可以设置期望并验证方法被调用的工具是Typemock Isolator。您正在寻找的未来被称为“未来对象”,它有助于设置行为并在被测试代码中“将被创建”的对象上验证它们:

[Fact]
public void PurgeOrder_should_log_action()
{
    var order = new Order();
    var logger = Isolate.Fake.Instance<IOrderLogger>();    
    var logAction = Isolate.Fake.Instance<LogAction>();
    Isolate.Swap.NextInstance<LogAction>().With(logAction);

    var service = new OrderService(logger);
    service.PurgeOrder(order);

    Isolate.Verify.WasCalledWithExactArguments(() => logger.Action(logAction));
}

答案 2 :(得分:0)

我会使用类似EasyMock的模拟,你可以在那里模拟IOrderLogger,然后做类似的事情:

IOrderLogger log = EasyMock.createMock(IOrderLogger.class);
log.Action(EasyMock.isA(LogAction.class));
EasyMock.expectLastCall();

这假设Action()返回void。这是一种非常Java的方式。我不确定EasyMock.net到底有多远。