使用 Moq 和 Nunit 的单元测试抛出“System.NullReferenceException”

发布于 2024-09-07 12:30:49 字数 1080 浏览 3 评论 0原文

我是最小起订量和单元测试的新手。所以,我并没有彻底理解它。如果问题很愚蠢请原谅我。请帮助我理解以下场景。

以下是我的简单测试

[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 =”foo“;”行 测试的代码正在抛出“System.NullReferenceException”。

为什么,我想原因是因为我使用了起订量。

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

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

    }

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

我只是想了解发生了什么事。我该如何最小起订量并验证子属性。

I am newbie to moq and unit testing. So, I don't understand it thoroughly. pardon me if question is stupid. please help me understand the following scenario.

Following is my simple test

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

and the code that I m trying to test

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

now at line "i.Model.MyProperty = "foo";" "System.NullReferenceException" is being thrown.

Why, I think the reason in since I m using Moq.

strange thing is that if i change the constructor of the "DummyClass". Like this

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

    }

Test Passes . In the second case even if I try changing the value of "foo" to "bar". Test Fails.(This is good though).

I just want to understand whats going on. and how am I suppose to moq and verify child properties.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

温柔女人霸气范 2024-09-14 12:30:49

两种情况之间的区别在于,当您编写时,

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

您本质上是在编写

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

,也就是说,您将一个属性已设置为“Foo”的对象传递给接口。您的测试断言“有人会尝试将 Mock 上的属性设置为 DummyModel 类型的对象,其中属性 MyProperty 设置为“Foo””,这正是正在发生的情况。

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

i.Model = new DummyModel();

直接在 Mock 上获取或设置属性不会设置该属性,它只会不执行任何操作或返回 null,除非您指定您希望它执行的操作。因此,在这种情况下,会发生的情况是,在构造函数的第二行中,i.Model 为 null,这会导致 i.Model.MyProperty 上出现 null 异常。

The difference between the two cases is that when you write

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

you are essentially writing

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

that is, you pass to your interface an object where the property is already set to "Foo". Your tests asserts that "someone will try to set the property on the Mock to an object of type DummyModel, where the property MyProperty is set to "Foo"", which is exactly what is happening.

The first case fails because after the following line executes, i.Model is null.

i.Model = new DummyModel();

Getting or setting a property on a Mock directly will NOT set the property, it will merely do nothing or return a null, unless you specify what you want it to do. So in that case what happens is that in the 2nd line of your constructor, i.Model is null, which causes the null exception on i.Model.MyProperty.

尛丟丟 2024-09-14 12:30:49

模拟不会记住属性的值,除非您告诉它:

i.Model = new DummyModel();

将导致模拟记住您将其设置为该对象。但是,如果您访问该属性,它仍然会返回 null。如果您希望它像自动属性一样运行,请使用:

mock.SetupAllProperties();

Now

i.Model.MyProperty = "foo";

将不再失败。对于模拟,您始终需要显式指定所有行为。

详细了解:http://code.google.com/p/moq/wiki/快速入门

The mock does not remember the value of the property unless you tell it to:

i.Model = new DummyModel();

will cause the mock to remember that you set it to that object. However it will still return null if you access the property. If you want it to behave like an automatic property, use:

mock.SetupAllProperties();

Now

i.Model.MyProperty = "foo";

will not fail anymore. With mocks you always need to specify all behavior explicitly.

Read more on: http://code.google.com/p/moq/wiki/QuickStart

萌酱 2024-09-14 12:30:49

您还可以执行以下操作:

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

Moq 的 m.Model 默认实现是返回 null,因此您需要为 Dummy() 提供比默认模拟更多的内容。

you can also do something like:

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

Moq's default implementation of m.Model is to return null, so you're going to need to give Dummy() something more than a default mock.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文