Frequently Asked Questions

ValueTuple

When I’m creating mocks for methods I often come across mock steps that take ``ValueTuple`` as parameters, but I didn’t have anything like that in my original interfaces - what’s going on?

Mocklis strives to map members of interfaces into one of four formats (for events, indexers, methods and properties respectively). In the case of a method the format is simply an ability to call the method with one parameter and one return type. If you have many parameters, they will be grouped together as named members of a value tuple, and in the case where you don’t have any parameters or a void return type, the ‘empty’ ValueTuple will be used. It is essentially just a struct with no members, and is the closest thing to a void type that the .net framework contains.

For the lambda steps (Func and Action, and the instance versions thereof) there are overloads that require the parameters to be of type ValueTuple, and the action versions require the return type to be a ValueTuple as well. This is simply to provide a nicer and terser syntax, but there is no way to prevent intellisense to suggest the fuller version as well. To make it a little bit more concrete, consider the following interface:

public interface IMisc
{
    void SayHello();
    int ScaleByTheAnswer(int p);
}

[MocklisClass]
public class Misc : IMisc
{
   . . .
}

When we are creating a mock for the SayHello method, we have four different (but ultimately equivalent) ways to go about it:

var misc = new Misc();

misc.SayHello.Action(() =>
{
    Console.WriteLine("Hello");
});

misc.SayHello.Action<ValueTuple>(_ =>
{
    Console.WriteLine("Hello");
});

misc.SayHello.Func<ValueTuple>(() =>
{
    Console.WriteLine("Hello");
    return ValueTuple.Create();
});

misc.SayHello.Func<ValueTuple, ValueTuple>(_ =>
{
    Console.WriteLine("Hello");
    return ValueTuple.Create();
});

Of course the compiler infers the type parameters - they’re just there for clarity. On the other hand for the ScaleByTheAnswer method, we only have one overload that works, since this method both accepts and returns stuff.

var misc = new Misc();

misc.ScaleByTheAnswer.Func<int, int>(i =>
{
    return i * 42;
});

Again the compiler infers the type parameters, and you can of course shorten the lambda considerably. But in short: you may be presented with steps that use ValueTuple, in which case it generally pays to look for versions of those steps that don’t.

“Missing” mock

When my mock is called, it throws a ``MockMissingException``. But I’m absolutely certain that I did provide a mock implementation. What’s going on?

Update: This now only happens when the MocklisClass attribute was declared with a VeryStrict = true parameter. The new behaviour (since version 0.2.0-alpha) for both lenient and strict (as in not ‘very strict’) mocks is that all steps assume an implicit Dummy step for all further extension points. In ‘very strict’ mode there is an implicit Missing step instead and an exception will be thrown.

You can think of the ‘very strict’ mode as ‘treat warnings as errors’. It’s a bit of a pain but it can help find issues with your mocks.

The solution is to chain a next step that does what you want the mock to do, be it a Dummy step, a Return step or anything else.

With an interface borrowed from the previous faq entry, here is a case which would throw the exception when used:

var misc = new Misc();

misc.ScaleByTheAnswer.Log();

The Log step will log the call, and then forward to the ‘default’ next step which (perhaps surprisingly) throws. Provide a next step as follows and it doesn’t throw:

var misc = new Misc();

misc.ScaleByTheAnswer.Log().Dummy();

And of course it doesn’t have to be Dummy(); - looking at the name of the method an appropriate mock might be .Func(i => i * 42);