单元测试使用Moq的(动态)方法

时间:2012-05-16 12:13:17

标签: c# unit-testing dynamic moq

我有以下方法:

public void Enqueue(ICommand itemToQueue)
{
    if (itemToQueue == null)
    {
        throw new ArgumentNullException("itemToQueue");
    }

    // Using the dynamic keywork to ensure the type passed in to the generic
    // method is the implementation type; not the interface.
    QueueStorage.AddToQueue((dynamic)itemToQueue);
}

QueueStorage是实现IQueueStorage的依赖项。我希望对它进行单元测试但是(动态)关键字似乎阻止了Moq正确绑定它。将关键字添加到队列时,该关键字用于正确分配具体的类类型而不是ICommand接口类型。

单元测试如下:

[Test]
public void Enqueue_ItemGiven_AddToQueueCalledOnQueueStorage()
{
    int timesAddToQueueCalled = 0;

    var dummyQueueStorage = new Mock<IQueueStorage>();
    var testCommand = new TestCommand();

    var queueManager = new AzureCommandQueueManager();

    dummyQueueStorage
        .Setup(x => x.AddToQueue(It.IsAny<TestCommand>()))
        .Callback(() => timesAddToQueueCalled++);

    queueManager.QueueStorage = dummyQueueStorage.Object;

    queueManager.Enqueue(testCommand);

    Assert.AreEqual(1, timesAddToQueueCalled);
}

虽然test命令是ICommand的空白实现:

private class TestCommand : ICommand
{
}

public interface ICommand
{
}

timesAddedToQueuCalled没有递增。我尝试使用It.IsAny<ICommand>(testCommand)无济于事。看起来好像没有执行Callback方法。谁能看到我做错了什么?

编辑:IQueueStorage代码:

public interface IQueueStorage
{
    void AddToQueue<T>(T item) where T : class;

    T ReadFromQueue<T>() where T : class;
}

1 个答案:

答案 0 :(得分:2)

以下代码可以正常运行:

public class AzureCommandQueueManager
{
    public void Enqueue(ICommand itemToQueue)
    {
        if (itemToQueue == null)            
            throw new ArgumentNullException("itemToQueue");

        QueueStorage.AddToQueue((dynamic)itemToQueue);
    }

    public IQueueStorage QueueStorage { get; set; }
}

public interface IQueueStorage
{
    void AddToQueue<T>(T command) where T : class;        
}

public class TestCommand : ICommand  {}

public interface ICommand {}

测试方法:

[Test]
public void Enqueue_ItemGiven_AddToQueueCalledOnQueueStorage()
{
    int timesAddToQueueCalled = 0;

    var dummyQueueStorage = new Mock<IQueueStorage>();
    var testCommand = new TestCommand();

    var queueManager = new AzureCommandQueueManager();

    dummyQueueStorage
        .Setup(x => x.AddToQueue(It.IsAny<TestCommand>()))
        .Callback(() => timesAddToQueueCalled++);

    queueManager.QueueStorage = dummyQueueStorage.Object;

    queueManager.Enqueue(testCommand);

    Assert.AreEqual(1, timesAddToQueueCalled);
}

我看到的唯一区别 - 你有privateTestCommand修饰符。顺便说一句,如果它是私有的,你如何从你的测试中访问该类?