Search code examples
rhino-mocks

Rhino moq Property.value constraint


My following straight forward test doesn't pass (Though I feel it should). Either I am missing something or is not clear of Property.value constraint. please help me in understanding concept of property.value constraint.

public interface ISomeInterface
{
     void SomeMethod(string x, string y);
}

public class SomeClassTest {

[Test]

public void SomeMethodTest()
    {

        MockRepository mocks = new MockRepository();
        ISomeInterface mockservice = mocks.StrictMock<ISomeInterface>();
        using (mocks.Record())
        {
            mockservice.SomeMethod("xValue", "yValue");
            LastCall.Constraints(Property.Value("x", "xValue"),
                                 Property.Value("y", "yValue"));
        }
        mockservice.SomeMethod("xValue", "yValue");
        mocks.Verify(mockservice);
    }
}

Exception raised:

Rhino.Mocks.Exceptions.ExpectationViolationException : ISomeInterface.SomeMethod("xValue", "yValue"); Expected #0, Actual #1. ISomeInterface.SomeMethod(property 'x' equal to xValue, property 'y' equal to yValue); Expected #1, Actual #0.


Solution

  • This sample class illustrates the options for asserting methods were called with appropriate properties:

    public class UsesThing
    {
       private IMyThing _thing;
    
       public UsesThing(IMyThing thing)
       {
          _thing = thing;
       }
    
       public void DoTheThing(int myparm)
       {
          _thing.DoWork(myparm, Helper.GetParmString(myparm));
       }
    
       public void DoAnotherThing(int myparm)
       {
           AnotherThing thing2 = new AnotherThing();
           thing2.MyProperty = myparm + 2;
           _thing.DoMoreWork(thing2)
        }
    }
    

    Using simple values for assertions may work for methods like the DoTheThing method which uses value types:

    [Test]
    public void TestDoTheThing()
    {
        IMyThing thing = MockRepository.GenerateMock<IMyThing>();
        UsesThing user = new UsesThing(thing);
    
        user.DoTheThing(1);
    
        thing.AssertWasCalled(t => t.DoWork(1, "one");
    }
    

    However, if you need to create an object in your method and pass it as a parameter like in the DoAnotherThing method, this approach will not work since you will not have a reference to the object. You have to check the property values of the unknown object, like this:

    [Test]
    public void TestDoAnotherThing()
    {
        IMyThing thing = MockRepository.GenerateMock<IMyThing>();
        UsesThing user = new UsesThing(thing);
    
        user.DoAnotherThing(1);
    
        thing.AssertWasCalled(t => t.DoMoreWork(null), t => t.IgnoreArguments().Constraints(Property.Value("MyProperty", 3))));        
    }
    

    The new Rhino syntax would look like the following, but I am crashing VS 2008 when I use it:

    thing.AssertWasCalled(t => t.DoMoreWork(Arg<AnotherThing>.Matches(Property.Value("MyProperty", 3))));