Moq vs Typemock – It.IsAny & It.Is

I kind of like the It.IsAny syntax and It.IsAny(validation expression) syntax of Moq. So now when I’m in the process of switching to Typemock I really was looking for this kind of API.

I have put together some simple samples to show the difference.

The difference in the APIs

#1

[Test]
public void VerifyCallWithExplicitArguments_WhenSameInstanceArgs_VerifiesOk()
{
    var args = new MyArgsWithoutEquals();
    var fake = new Mock<MyClassUnderTest>();

    var invoker = new Invoker(fake.Object);
    invoker.Invoke(args);

    fake.Verify(f => f.MyMethod(args));
}
[Test, Isolated]
public void VerifyCallWithExplicitArguments_WhenSameInstanceArgs_VerifiesOk()
{
    var args = new MyArgsWithoutEquals();
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();

    var invoker = new Invoker(fake);
    invoker.Invoke(args);

    Isolate.Verify.WasCalledWithExactArguments(
        () => fake.MyMethod(args));
}

#2

[Test]
public void VerifyCallWithExplicitArguments_WhenOtherInstanceArgs_ThrowsMockException()
{
    var args = new MyArgsWithoutEquals();
    var argsOther = new MyArgsWithoutEquals();
    var fake = new Mock<MyClassUnderTest>();

    var invoker = new Invoker(fake.Object);
    invoker.Invoke(argsOther);

    Assert.Throws<MockException>(
        () => fake.Verify(f => f.MyMethod(args)));
}
[Test, Isolated]
public void VerifyCallWithExplicitArguments_WhenOtherInstanceArgs_ThrowsMockException()
{
    var args = new MyArgsWithoutEquals();
    var argsOther = new MyArgsWithoutEquals();
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();

    var invoker = new Invoker(fake);
    invoker.Invoke(argsOther);

    Assert.Throws<VerifyException>(
        () => Isolate.Verify.WasCalledWithExactArguments(
            () => fake.MyMethod(args)));
}

#3

[Test]
public void VerifyCallWithExplicitArgumentsAndValues_WhenOtherInstanceArgsWithSameValues_VerifiesOk()
{
    var args = new MyArgsWithoutEquals { Id = 1 };
    var argsOther = new MyArgsWithoutEquals { Id = 1 };
    var fake = new Mock<MyClassUnderTest>();

    var invoker = new Invoker(fake.Object);
    invoker.Invoke(argsOther);

    fake.Verify(f => f.MyMethod(It.Is<MyArgsWithoutEquals>(a => a.Id == args.Id)));
}
[Test, Isolated]
public void VerifyCallWithExplicitArgumentsAndValues_WhenOtherInstanceArgsWithSameValues_VerifiesOk()
{
    var args = new MyArgsWithoutEquals { Id = 1 };
    var argsOther = new MyArgsWithoutEquals { Id = 1 };
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();

    var invoker = new Invoker(fake);
    invoker.Invoke(argsOther);

    Isolate.Verify.WasCalledWithArguments(
        () => fake.MyMethod(args)).Matching(a => ((MyArgsWithoutEquals)a[0]).Id == args.Id);
}

#4

[Test]
public void VerifyCallWithExplicitArguments_WhenOtherInstanceArgsWithEqualsImplementation_VerifiesOk()
{
    var args = new MyArgsWithEquals();
    var argsOther = new MyArgsWithEquals();
    var fake = new Mock<MyClassUnderTest>();

    var invoker = new Invoker(fake.Object);
    invoker.Invoke(argsOther);

    fake.Verify(f => f.MyMethod(args));
}
[Test, Isolated]
public void VerifyCallWithExplicitArguments_WhenOtherInstanceArgsWithEqualsImplementation_VerifiesOk()
{
    var args = new MyArgsWithEquals();
    var argsOther = new MyArgsWithEquals();
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();

    var invoker = new Invoker(fake);
    invoker.Invoke(argsOther);

    Isolate.Verify.WasCalledWithExactArguments(
        () => fake.MyMethod(args));
}

#5

[Test]
public void VerifyCallWithAnyArguments_WhenInstanceOfCorrectType_VerifiesOk()
{
    var args = new MyArgsWithoutEquals();
    var fake = new Mock<MyClassUnderTest>();

    var invoker = new Invoker(fake.Object);
    invoker.Invoke(args);

    fake.Verify(f => f.MyMethod(It.IsAny<MyArgsWithoutEquals>()));
}
[Test, Isolated]
public void VerifyCallWithAnyArguments_WhenInstanceOfCorrectType_VerifiesOk()
{
    var args = new MyArgsWithoutEquals();
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();
            
    var invoker = new Invoker(fake);
    invoker.Invoke(args);

    Isolate.Verify.WasCalledWithAnyArguments(() => fake.MyMethod(null));
}

Test duration

I also spotted something else. The difference in duration of the tests. Even though this isn’t a realistic scenario, since I only have five tests, I thinkt it’s kind of fun to see. It would be interesting to swap in a real scenario where there’s alot of faking going on.
Moq vs Typemock - Test duration

When doing these tests I was consuming:

  • Moq v4.0.10501.6 (what’s with all these decimals. I just wan’t to be able to determine older/never)
  • Typemock v6.0.3.0

I also tested to disable Typemock and to run the Moq test alone. The result was the same.

Download the code here

The conclusions

Conclusion #1
Regarding to the It.IsAny and It.Is(validation expression), the conclusion is that the only API member I’m missing, is the It.IsAny. Why? Because I really don’t like the way I have to pass null to WithAnyArguments, in Typemock. I really hope they implement something similar. And if they have, please correct me.

Conclusion #2
I also would like Typemock to provide me a solution where I don’t have to verify against an object[] as in code example #3 above.

Conclusion #3
I like the way Typemock uses “Fakes” instead of “Mocks”. This since Fakes covers both Stubs and Mocks, while the Moq framework lets Mock represent both Stubs and Mocks, which is somewhat confusing.

So, so far I’m happy with the invested money in Typemock.

//Daniel

3 thoughts on “Moq vs Typemock – It.IsAny & It.Is

  1. Pingback: Moq vs TypeMock – Simple solution to It.IsAny « Daniel Wertheim

  2. Pingback: Moq vs Typemock – Simple solution to It.Is(expression) « Daniel Wertheim

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s