2012-05-16 108 views
0

我有以下方法,使用的方法(动态):单元测试使用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); 
} 

虽然测试命令是一个空白实现的ICommand的:

private class TestCommand : ICommand 
{ 
} 

public interface ICommand 
{ 
} 

timesAddedToQueuCalled不被递增。我试过使用It.IsAny<ICommand>(testCommand)无济于事。它看起来像回调方法没有被执行。任何人都可以看到我做错了什么?

编辑:IQueueStorage代码:

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

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

我没有看到你需要'动态'。为什么AddToQueue()参数的类型是否是一个接口?无论如何,实际的类型不能是接口 – Attila

+0

你提供的代码工作正常。 IQueueStorage中有几个重载的AddToQueue方法吗? –

+0

@Attila我正在使用Azure队列存储;如果您在使用XMLSerializer和通用方法的同时需要知道序列化到队列的内容。 –

回答

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

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

+0

这个类是嵌入Test类的 –

+0

我的天;它是'私人'修饰符;使其成为'public'意味着'AzureCommandQueueManager'可以读取它。感谢您的帮助! –

+0

@ Click-Rex欢迎您:) –