【问题标题】:Verify that method is called within Action验证是否在 Action 中调用了该方法
【发布时间】:2015-11-12 13:53:44
【问题描述】:

这些天我经常练习单元测试,如果我无法理解一些基础知识,请多多包涵。

拥有这些简单的抽象:

public interface ITaskFactory
{
    void StartTask(Action action);
}

internal sealed class TaskFactory : ITaskFactory
{
    public void StartTask(Action action)
    {
        Task.Factory.StartNew(action);
    }
}

以及要测试的这个类(简化为这种情况):

internal sealed class TriggerEventDecorator<TEvent> : ITriggerEvent<TEvent> where TEvent : IEvent
{
    private readonly ITaskFactory _taskFactory;
    private readonly Func<ITriggerEvent<TEvent>> _factory;

    public TriggerEventDecorator(ITaskFactory taskFactory, Func<ITriggerEvent<TEvent>> factory)
    {
        _taskFactory = taskFactory;
        _factory = factory;
    }

    public void Trigger(TEvent evt)
    {
        _taskFactory.StartTask(() =>
        {
            _factory().Trigger(evt);
        });
    }
}

我对这门课的测试:

public class TriggerEventDecoratorTests
{
    [Fact]
    public void CanTriggerEventHandler()
    {
        var evt = new FakeEventWithoutValidation();
        Assert.IsAssignableFrom<IEvent>(evt);

        var decorated = new Mock<ITriggerEvent<FakeEventWithoutValidation>>(MockBehavior.Strict);
        decorated.Setup(x => x.Trigger(evt));

        var taskFactory = new Mock<ITaskFactory>(MockBehavior.Strict);
        taskFactory.Setup(factory => factory.StartTask(It.IsAny<Action>()));

        var decorator = new TriggerEventDecorator<FakeEventWithoutValidation>(taskFactory.Object, () => decorated.Object);
        decorator.Trigger(evt);

        taskFactory.Verify(x => x.StartTask(It.IsAny<Action>()), Times.Once);
        decorated.Verify(x => x.Trigger(evt), Times.Once); // This line is not verified
    }
}

decorated.Verify(x =&gt; x.Trigger(evt), Times.Once); 行未经验证,从未调用过。

如何测试这是在_taskFactoryAction 中触发的?

【问题讨论】:

  • 一般来说,当一个单元测试中有多个Mock时,就意味着开发者迷茫了,迷失了方向。在这里,我认为它发生了。你要测试什么?如果你想测试TriggerEventDecorator 那为什么会被嘲笑呢?

标签: c# unit-testing moq xunit


【解决方案1】:

您没有调用Func 方法。这就是问题所在...为此,您必须使用Callback 方法。

更改以下设置:

taskFactory.Setup(factory => factory.StartTask(It.IsAny<Action>()));

收件人:

taskFactory.Setup(factory => factory.StartTask(It.IsAny<Action>()))
           .Callback<Action>((action) => action());

【讨论】:

  • 非常感谢,现在开始使用.Callback(..)!再次感谢! :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-12
  • 1970-01-01
  • 2020-05-26
  • 2014-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多