代码之家  ›  专栏  ›  技术社区  ›  mxmissile

单元测试留桩法

  •  3
  • mxmissile  · 技术社区  · 15 年前

    给定这个类:

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

    显然测试是错误的。我如何声明OrthLogLog.Action(…)在这个场景中实际上被调用?如果logAction是在purgorder方法中实例化的,我不知道它是如何实现的。有什么建议吗?

    3 回复  |  直到 15 年前
        1
  •  1
  •   Grzenio    15 年前

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

        2
  •  1
  •   Dror Helper    15 年前

    [免责声明 Typemock ]

    据我所知,唯一的工具,可以设置预期和验证方法被称为类型锁隔离器。您正在寻找的未来称为“未来对象”。它有助于设置行为,并在测试代码中“将创建”的对象上验证它们:

    [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));
    }
    
        3
  •  0
  •   jaketrent    15 年前

    我会使用mocks,比如easymock,你可以在这里模拟iordrogger,然后做如下操作:

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

    这假设action()返回void。这是一个非常类似Java的方式。我不知道这条路有多远 EasyMock.net 已经来了。