tags:

views:

64

answers:

3

Hi All,

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.

+1  A: 

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

arneeiri
Thanks "arneeiri" for the solution of the problem. But, I was looking for the explanation. But, SetupAllProperties solves it for me, Thanks a lot.
Mohit
+1  A: 

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.

Mathias
Thanks for the nice explanation. Along with your answer. I liked the "arneeiri" reply as well, since it solves my problem :)
Mohit
+1  A: 

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.

Frank Schwieterman