janhartmann
janhartmann

Reputation: 15003

Verify that method is called within Action

I am practicing unit-testing a lot of these days, so bear with me if I fail to understand some basics.

Having these simple abstractions:

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

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

And this class to test (simplified to this case):

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

And my test of this class:

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

The line decorated.Verify(x => x.Trigger(evt), Times.Once); is not verified, it is never invoked.

How do I test that this is trigged in the Action of the _taskFactory?

Upvotes: 2

Views: 1724

Answers (1)

Old Fox
Old Fox

Reputation: 8725

You didn't invoke the Func method. This is the problem... To do so you'll have to use Callback method.

Change the following sertup:

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

To:

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

Upvotes: 1

Related Questions