2013-10-23 54 views
1

使用参数化构造函数嘲讽对象时,如果在构造函数中初始化的属性是虚拟的,则Moq不会设置属性值。但是,如果它是非虚拟财产,Moq设置价值。使用虚参数和参数构造函数的Moq行为

以下是我的课我想嘲笑。

public class Activity 
{ 
    private Activity() {} 
    public Activity(string code, string description, string option) 
    { 
     if(string.IsNullOrEmpty(code)) throw new ArgumentNullException("code"); 
     if (string.IsNullOrEmpty(option)) throw new ArgumentNullException("option"); 

     Code = code; 
     Description = description; 
     Option = option; 
    } 

    public virtual string Code { get; private set; } 
    public virtual string Description { get; private set; } 
    public virtual string Option { get; private set; } 

} 

这是我尝试嘲笑它:

[TestMethod] 
    public void It_Creates_Mock_For_A_Class() 
    { 
     var mock = new Mock<Activity>("Code 1", null, "Option"); 
     Assert.IsNotNull(mock.Object); 
     Assert.AreEqual("Code 1", mock.Object.Code); 
    } 

测试方法失败说: Assert.AreEqual失败。预期:。实际:<(null)>。

但是,如果我从所有属性中删除virtual关键字,它将起作用并通过测试用例。

由于实体框架的原因,我必须保持属性的虚拟性。

任何线索?如何解决这个问题?

+0

其实测试的测试MOQ框架,而不是测试你的构造函数的实现。你想测试什么?你只问过最奇怪的MOQ行为吗? –

+0

@IlyaPalkin上面只是一个例子,用于演示我在Moq遇到的虚拟/非虚拟属性时遇到的问题。由于这个问题,我试图编写的很多行为测试用例都失败了,因为Activity类的私有方法在内部使用这些属性并找到它们为空。 – 101V

回答

1

发现如果“CallBase”属性设置为true,它解决了问题。

通过查看对象浏览器的组装,总结说:

摘要: 无论如果没有安装匹配的底座部件虚拟实现将呼吁嘲笑类。默认为false。

,工程代码:

[TestMethod] 
    public void It_Creates_Mock_For_A_Class() 
    { 
     var mock = new Mock<Activity>("Code 1", null, "Option"); 
     mock.CallBase = true; 
     Assert.IsNotNull(mock.Object); 
     Assert.AreEqual("Code 1", mock.Object.Code); 
    } 
+0

我没有使用'mock.CallBase = true;'之前,但它是我将来肯定会使用的东西。无论如何,我认为还有其他更好的解决方案。 –

+0

@IlyaPalkin你可以请分享更好的解决方案。 – 101V

+1

**如果您测试依赖于“活动”**的课程,那么您将创建“模拟”并设置其公共属性或方法。在这种情况下,被测单元就是该类的一个实例。 **如果你测试'Activity'**,那么你应该测试一个'Activity'类型的实例。所有私有方法通常通过公共方法进行测试。 –