Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Verify to confirm expected parameter values in Moq mock class

I'm trying to verify that a method within a mock is called with an expected object parameter. I'm using Moq, nUnit, and thinking that AutoFixture's Likeness should get the job done. Below is a simplified version of what i'm trying to do.

Is there a way to do this with AutoFixture? Is there a better way to verify that Something is called with the appropriate parameter?

Overriding Equals in the A class to compare the property values and changing the Verify line to:

barMock.Verify(m => m.Something(a)); 

passes, however I'd rather not override Equals in every class like A in my project.

namespace Test {     using Moq;     using NUnit.Framework;     using Ploeh.SemanticComparison.Fluent;      public class A     {         public int P1 { get; set; }     }     public interface IBar     {         void Something(A a);     }      public class Foo     {         public A Data { get; private set; }         public void DoSomethingWith(IBar bar)         {             Data = new A { P1 = 1 };             bar.Something(Data);         }     }      [TestFixture]     public class AutoFixtureTest     {         [Test]         public void TestSample()         {             var foo = new Foo();             var barMock = new Mock<IBar>();             var a = new A { P1 = 1 };             var expectedA = a.AsSource().OfLikeness<A>();              foo.DoSomethingWith(barMock.Object);              expectedA.ShouldEqual(foo.Data);   // passes             barMock.Verify(m => m.Something(expectedA.Value));  // fails         }     } } 
like image 904
jaminto Avatar asked Jan 16 '12 17:01

jaminto


People also ask

What is verify in mock in C#?

mock. Verify(p => p. Send(It. IsAny<string>())); The Verify method offers additional overloads to specify the fail message and the amount of times the invocation was expected to be performed.

What is verifiable in MOQ?

Verifiable(); 'Setup' mocks a method and 'Returns' specify what the mocked method should return. 'Verifiable' marks this expectation to verified at the end when Verify or VerifyAll is called i.e. whether AddIncomePeriod was called with an object of IncomePeriod and if it returned the same output.


2 Answers

In Verify Moq by default checks reference equality for arguments so it only passes when you provide the same instances (except if you've overriden Equals) in your tests and in your implementation.

In you case the expectedA.Value just returns the new A { P1 = 1 } created in the test which, of course, isn't the same instance created in DoSomethingWith.

You need to use Moq's It.Is construct to properly test this without overriding Equals (in fact for this you don't need Autofixture at all):

barMock.Verify(m => m.Something(It.Is<A>(arg => arg.P1 == a.P1))); 

But if you have multiple properties like P1,P2,P3... AutoFixture can be useful:

barMock.Verify(m => m.Something(It.Is<A>(arg => expectedA.Equals(a)))); 

Because you don't need to write out the equality checks manually for all the properties.

like image 64
nemesv Avatar answered Sep 22 '22 09:09

nemesv


If you upgrade to AutoFixture 2.9.1 (or newer) you can call the CreateProxy method on the Likeness instance which will emit a dynamic proxy for the destination type.

The generated dynamic proxy overrides Equals using Likeness which simplifies the syntax (quite a lot).

Here is the original test method, modified to use the Likeness proxy:

[Test] public void TestSample() {     var foo = new Foo();     var barMock = new Mock<IBar>();     var expected = new A().AsSource().OfLikeness<A>().CreateProxy();     expected.P1 = 1;      foo.DoSomethingWith(barMock.Object);      Assert.True(expected.Equals(foo.Data));     // passes     barMock.Verify(m => m.Something(expected)); // passes } 

Note that it also makes the test assertion much more specific than accepting Any instance.

You can find more details on this new feature here.

like image 24
Nikos Baxevanis Avatar answered Sep 18 '22 09:09

Nikos Baxevanis