验证在Action中调用该方法

时间:2015-11-12 13:53:44

标签: c# unit-testing moq xunit

这些天我正在练习单元测试,所以如果我不理解一些基础知识,请耐心等待。

有这些简单的抽象:

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 => x.Trigger(evt), Times.Once);,永远不会调用它。

如何测试这是Action的{​​{1}}触发的?

1 个答案:

答案 0 :(得分:1)

您没有调用Func方法。这就是问题......要做到这一点,你必须使用Callback方法。

更改以下sertup:

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

要:

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