4

I'm using Rhino Mocks 3.5 to mock a service method call which takes 2 parameters and I want to make sure a propery on an object is being set correctly.

// Method being tested
void UpdateDelivery( Trade trade )
{
    trade.Delivery = new DateTime( 2013, 7, 4 );
    m_Service.UpdateTrade( trade, m_Token ); // mocking this
}

Here's a portion of my code (which works)

service, trade, token declared / new'd up ... etc.
...

using ( m_Mocks.Record() )
{
    Action<Trade, Token> onCalled = ( tradeParam, tokenParam ) =>
            {
                // Inspect / verify that Delivery prop is set correctly
                // when UpdateTrade called
                Assert.AreEqual( new DateTime( 2013, 7, 4 ), tradeParam.Delivery );                     
            };

    Expect.Call( () => m_Service.UpdateTrade( Arg<Trade>.Is.Equal( trade ), Arg<Token>.Is.Equal( token ) ) ).Do( onCalled );
}

using ( m_Mocks.Playback() )
{
    m_Adjuster = new Adjuster( service, token );
    m_Adjuster.UpdateDelivery( trade );
}

Is there a better, more concise, straightfoward way to test this using Rhino Mocks? I've seen posts where Contraints are used but I'm not a fan of identifying properties / value by string names.

Alexander Stepaniuk
  • 6,217
  • 4
  • 31
  • 48
KornMuffin
  • 2,887
  • 3
  • 32
  • 48

1 Answers1

6

You can do the following:

Expect.Call(() => m_Service.UpdateTrade(
    Arg<Trade>.Matches(t => t.Delivery.Equals(new DateTime(2013, 7, 3))),
    Arg<Token>.Is.Anything)
);

Please also note, if you are not going to validate token parameter in this tests, then you can use Is.Anything constraint for it.


Note:

RhinoMocks 3.5 and .NET4+ throw an AmbiguousMatchException when using the Matches(Expression<Predicate<..>>) overload. If it is not possible to update to RhinoMocks 3.6 (there are reasons), one can still use the Matches(AbstractConstraint) overload as so:

 Arg<Trade>.Matches(
   Property.Value("Delivery", new DateTime(2013, 7, 3)))

or:

 Arg<Trade>.Matches(
   new PredicateConstraint<DateTime>(
     t => t.Delivery.Equals(new DateTime(2013, 7, 3))))
user2864740
  • 60,010
  • 15
  • 145
  • 220
Alexander Stepaniuk
  • 6,217
  • 4
  • 31
  • 48
  • 1
    Thanks Alexander. This is exactly what I was looking for. I receive "System.Reflection.AmbiguousMatchException : Ambiguous match found." when I run though. I'm using .Net 4.0 – KornMuffin Jul 11 '13 at 13:07
  • What method are you getting this exception for? – Alexander Stepaniuk Jul 12 '13 at 10:49
  • Raised by Rhino Mocks when the m_Service.UpdateTrade method is called within the class being tested. System.Reflection.AmbiguousMatchException : Ambiguous match found. at System.RuntimeType.GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv, Type[] types, ParameterModifier[] modifiers) at System.Type.GetMethod(String name) at Rhino.Mocks.Constraints.LambdaConstraint.Eval(Object obj) at Rhino.Mocks.Expectations.ConstraintsExpectation.DoIsExpected(Object[] args) at Rhino.Mocks.Expectations.AbstractExpectation.IsExpected(Object[] args)... – KornMuffin Jul 16 '13 at 14:34
  • 1
    are there any overloads for method `UpdateTrade()`? Can you add the definition of interface/class which contains method `UpdateTrade()`? – Alexander Stepaniuk Jul 17 '13 at 10:43
  • 2
    Looks like it's an issue with Rhino 3.5. I downloaded 3.6 and the tests pass. Here's a [link](http://blogs.microsoft.co.il/blogs/ndobkin/archive/2010/12/18/rhino-mocks-3-5-with-framework-4.aspx) to a blog. Thanks again for your answer. – KornMuffin Jul 29 '13 at 21:04
  • 1
    @KornMuffin (And those like me who 'must' use Rhino 3.5) The "Ambiguous match found" is only caused when using the Expression overload of Matches. The overload taking in an AbstractConstraint works as expected. – user2864740 Aug 12 '17 at 01:03