Moq vs Typemock – Simple solution to It.Is(expression)

So I thought I just add one more post about this subject. Previous posts:

As I stated I don’t like the predicate that gives me an object[0], so why not do something about it.

public static class IArgumentsMatcherExtensions
{
    public static void Matching<T>(this IArgumentsMatcher matcher, Predicate<T> verify)
    {
        matcher.Matching(args => verify.Invoke((T)args[0]));
    }
}

With this code I can now write tests like:

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

    Isolate.Verify.WasCalledWithArguments(
        () => fake.MyMethod(args)).Matching<IMyArgs>(a1 => a1.Id == 1);
}

Instead of

[Test]
public void TheTest4()
{
    var args = new MyArgsWithoutEquals();
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();
    fake.MyMethod(args);

    Isolate.Verify.WasCalledWithArguments(
        () => fake.MyMethod(args)).Matching(x => ((IMyArgs)x[0]).Id == 1);
}

I hope I will see something like this in Typemock in the future.

//Daniel

Moq vs TypeMock – Simple solution to It.IsAny

So I just posted this post where I wanted the It.IsAny syntax in Typemock. Without giving any long thought on this I wrote two simple solutions:

Solution 1

public static class IVerifyHandlerExtensions
{
    public static void WasCalledWithAnyArguments<T>(this IVerifyHandler handler, Action<T> action)
    {
        handler.WasCalledWithAnyArguments(() => action.Invoke(default(T)));
    }
}
[Test, Isolated]
public void TheTest()
{
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();
    fake.MyMethod(new MyArgsWithoutEquals());

    Isolate.Verify.WasCalledWithAnyArguments<MyArgsWithoutEquals>(fake.MyMethod);
}

Solution 2

public static class IsAny<T>
{
    public static T Item = default(T);
}
[Test, Isolated]
public void TheTest2()
{
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();
    fake.MyMethod(new MyArgsWithoutEquals());

    Isolate.Verify.WasCalledWithAnyArguments(() => fake.MyMethod(IsAny<IMyArgs>.Item));
}

As I said. Not much thinking in there so I’m probably missing something. It worked for me. Now I don’t have to type “null” any more.

//Daniel

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

Typemock – Beautiful exceptions

So I recently started to use Typemock instead of Moq and I’m currently getting acquainted with the API. I just found something that I really think shows that they are putting in some effort to the product. It’s no fancy feature just something that I think every Mocking-framework should provide: “Informative and guiding exceptions when you use the framework inappropriately.”

Take this for an example:

[Test, Isolated]
public void Execute_WhenNoNotationExistsAndDateIsToday_RegistrationIsAllowed()
{
    var scenario = new RegisterSleepNotationScenario().ConfigureParams(
        p => p.NewSleepNotation = new SleepNotation(new Kid(), Week.Current, DayOfWeek.Monday, 1, 50));
    var sleepNotationsSourceFake = Isolate.Fake.Instance<IEditableObjectSource<SleepNotation>>();
    scenario.SleepNotaionsSource = sleepNotationsSourceFake;

    scenario.Execute();

    Isolate.Verify.WasCalledWithExactArguments(
        () => sleepNotationsSourceFake.Insert(scenario.Params.NewSleepNotation));
}

This test resulted in the following exception from Typemock:

This informative message then lead me to the small change:

var expectedNewSleepNotation = scenario.Params.NewSleepNotation;
Isolate.Verify.WasCalledWithExactArguments(() => sleepNotationsSourceFake.Insert(expectedNewSleepNotation));

Which resulted in a green test and a happy developer, without having to use Google or the Typemock-documentations to search for: “how to consume WasCalledWithExactArguments”. As it should be. Thank you Typemock!

//Daniel