2010-06-30 119 views
1

我是moq和单元测试的新手。所以,我不完全理解它。如果问题是愚蠢的,请原谅我。请帮助我了解以下情况。单元测试抛出“System.NullReferenceException”,使用Moq和Nunit

以下是我简单的测试

[Test] 
public void TryMoq() { 
    var mock = new Mock<IDummyInterface>(); 
    var dummy = new DummyClass(mock.Object); 
    mock.VerifySet(m => m.Model = It.Is<DummyModel>(mo => mo.MyProperty == "foo")); 
} 

和我米试图测试

public class DummyClass 
{ 
    public DummyClass(IDummyInterface i) { 
     i.Model = new DummyModel() ; 
     i.Model.MyProperty = "foo"; 

    } 
} 

public class DummyModel 
{ 
    public string MyProperty { get; set; } 
} 

public interface IDummyInterface { 
    DummyModel Model { get; set; } 
} 

现在行 “i.Model.MyProperty = ”富代码“;” “System.NullReferenceException”正在被抛出。

为什么我认为自从我使用Moq以来的原因。

奇怪的是,如果我改变了“DummyClass”的构造函数。像这样

public DummyClass(IDummyInterface i) 
    { 
     i.Model = new DummyModel() { MyProperty ="foo"}; 
     //i.Model.MyProperty = "foo"; 

    } 

测试通行证。在第二种情况下,即使我尝试将“foo”的值更改为“bar”。测试失败(虽然这很好)。

我只是想了解发生了什么事情。以及我想如何检查和验证孩子的财产。

回答

1

两种情况之间的区别是,当你写

i.Model = new DummyModel() { MyProperty ="foo"}; 

你基本上是写

var dummyModel = new DummyModel() { MyProperty ="foo"}; 
i.Model = dummyModel; 

也就是说,你传递给你的界面该属性已被设置为“Foo”的对象。您的测试声明“有人会尝试将Mock上的属性设置为DummyModel类型的对象,其中属性MyProperty设置为”Foo“”,这正是发生的情况。

第一种情况失败,因为执行以下行后,i.Model为空。

i.Model = new DummyModel(); 

获取或直接设置在一个模拟的属性将不设置该属性,它只会什么也不做,或者返回一个空,除非你指定你想要它做的事情。所以在这种情况下,会发生什么情况是,在构造函数的第二行中,i.Model为null,这会导致i.Model.MyProperty上的null异常。

+0

感谢您的好解释。随你的答案。我也很喜欢“arneeiri”的回复,因为它解决了我的问题:) – Mohit 2010-06-30 21:43:34

2

的模拟不记得财产的价值,除非你告诉它:

i.Model = new DummyModel(); 

将导致模拟要记住,你将其设置为对象。但是,如果您访问该属性,它仍然会返回null。如果你希望它表现得像一个自动特性,使用方法:

mock.SetupAllProperties(); 

现在

i.Model.MyProperty = "foo"; 

不会失败了。通过模拟,您总是需要明确指定所有行为。

了解更多关于:http://code.google.com/p/moq/wiki/QuickStart

+0

感谢“arneeiri”解决问题。但是,我正在寻找解释。但是,SetupAllProperties为我解决了这个问题,非常感谢。 – Mohit 2010-06-30 21:45:11

1

你也可以这样做:

var mock = new Mock<IDummyInterface>(); 
mock.SetupSet(m => m.Model = It.Is<DummyModel>(mo => mo.MyProperty == "foo")).Verifiable(); 

var dummy = new DummyClass(mock.Object); 

mock.Verify(); 

起订量的m.Model的默认实现是返回NULL,所以你将需要给假人()的东西比一个默认的模拟多。