Parsing “Unsafe” Method Signatures

If you’ve ever used JustMock then you should be familiar with code fragments like this one:

public interface IFoo
{
    byte Bar(int i, string s, long l);
}

var foo = Mock.Create<IFoo>();
Mock.Arrange(() => foo.Bar(123, "test", 321)).Returns(5);

The interesting thing in this code is in the Arrange method. Its signature is as follows:

public static FuncExpectation<TResult> Arrange<TResult>(Expression<Func<TResult>> expression)

The method accepts a single parameter of Expression<TDelegate> type. This allows JustMock to parse the actual method name and the parameter values. In this blog post I am going to show you a simple and yet effective approach for parsing methods that contain pointer parameters.

Lets make our example more interesting.

public unsafe interface IFoo
{
    byte** Bar(int* i, string s, ref long* l);
}

Because Expression<TDelegate> expects a delegate type as a type parameter we can define a new delegate type and use it to construct a proper expression object.

public unsafe delegate byte** BarDel();
//..
int* pi = (int*)IntPtr.Zero;
long* pl = (long*)IntPtr.Zero;
Expression<BarDel> expr = () => Bar(pi, "test", ref pl);

This is all good and nice. Now we can change Arrange method signature as follows:

// to keep it simple, we changed the return type to void
public static void Arrange<TDelegate>(Expression<TDelegate> expr) { }
//..
int* pi = (int*)IntPtr.Zero;
long* pl = (long*)IntPtr.Zero;
Mock.Arrange<BarDel>(() => Bar(pi, "test", ref pl));

The only thing that left is to make the return type independent from the return type of the actual Bar method. This is easy. A pointer to a pointer to a byte (byte**) is just… a pointer! The only tricky thing is that JustMock doesn’t know what actual type is pointed. So, it is a sane decision to leave this knowledge to the unit test author. We need a simple generalization over IntPtr type and that’s all.

namespace Telerik.JustMock
{
    public class PtrBase
    {
        private readonly IntPtr addr;

        protected PtrBase(IntPtr addr)
        {
            this.addr = addr;
        }

        public IntPtr Addr { get { return this.addr; } }
    }

    public delegate T PtrDel<T>() where T : PtrBase;
}

Now, we have to change Arrange method as follows:

public static void Arrange<TPtr>(Expression<PtrDel<TPtr>> expr, params TPtr[] arr)
    where TPtr : PtrBase
{
    var methodCallExpr = (expr.Body as UnaryExpression).Operand as MethodCallExpression;

    // process methodCallExpr
}

Lets see how we have to change our test code so we can call the new Arrange method. Now, we have to take care for all pointers and convert them. This is a trivial task:

public class Ptr : PtrBase
{
    private Ptr(IntPtr addr) : base(addr) { }

    public unsafe static implicit operator Ptr(int* ptr)
    {
        return new Ptr(new IntPtr(ptr));
    }

    public unsafe static implicit operator Ptr(long* ptr)
    {
        return new Ptr(new IntPtr(ptr));
    }

    public unsafe static implicit operator Ptr(byte** ptr)
    {
        return new Ptr(new IntPtr(ptr));
    }
}

Finally, we have to change our Arrange method invocation:

int* pi = (int*)IntPtr.Zero;
long* pl = (long*)IntPtr.Zero;
Mock.Arrange<Ptr>(() => Foo(pi, "test", ref pl), pi, pl);

The code can be improved in many ways. One way to improve it is to replace PtrDel<T> with Func<TResult> though I prefer the explicit constraint on PtrBase. Another way to improved the code is by making PtrBase abstract type and providing a template method that will be called inside the Arrange method, so the actual value can be retrieved. Here is a simple implementation:

namespace Telerik.JustMock
{
    public abstract class PtrBase
    {
        private readonly IntPtr addr;
        private readonly int cookie;

        protected PtrBase(IntPtr addr, int cookie)
        {
            this.addr = addr;
            this.cookie = cookie;
        }

        public IntPtr Addr { get { return this.addr; } }
        public int Cookie { get { return this.cookie; } }

        public abstract object ReadValue();
    }
}

When you create a new type which inherits from PtrBase type you should provide a unique cookie for each pointer type (e.g. 1 for int*, 2 for long*, 3 for byte**, etc.). When Arrange method is called, it will call in turn your implementation of ReadValue method and use the return value. In a matter of fact we don’t need this cookie mechanism because we can get the actual pointer type from methodCallExpr variable. The real purpose of ReadValue is to allow execution of user defined code in a lazy fashion. In case you don’t want this feature you can read the actual pointed value inside Ptr implicit conversion operator implementation and pass it to PtrBase constructor.

JustMock Design Choices

JustMock is a small product. It is around 10,000 lines of code. Despite its small size there are a lot of decisions that were made and many others that have to be made. In this post I would like to shed some light on our decision making process and I’ll try to answer the question why JustMock is built the way it is. The topic is quite large for a single blog post so I am going to focus on small part from JustMock – namely design choices for private method resolution.

First, I would like to emphasize that JustMock was built around C#. Every time when we had to decide how particular feature should be implemented we designed it from C# perspective. As a result JustMock works with concepts that are better expressed in C# rather than VB.NET for example. The reason for this decision is that it seems C# developers tend to use more often mocking tools/frameworks than VB.NET ones. So far, it seems we did the right choice.

As a consequence JustMock is more or less tightly coupled to the C# compiler. So are other mocking libraries. Lets consider the following example with Moq:

    public interface IFoo
    {
        int Bar(string s);
        int Bar(StringBuilder s);
    }

Often, it makes sense to define overloading methods in your code. The way IFoo is defined is perfectly legal. So, lets see a corner case with this interface. Suppose we want to mock Bar(string s) method when the argument is null:

    var mock = new Mock<IFoo>();
    mock.Setup(foo => foo.Bar(null)).Returns(1);

You will quickly find that the this code fragment does not compile. Here goes the error:

error CS0121: The call is ambiguous between the following methods or properties:
'IFoo.Bar(string)' and 'IFoo.Bar(System.Text.StringBuilder)'

This error has nothing to do with Moq. It is related to the C# compiler which in this case does not have enough information how to do method resolution. So, it is our fault and we have to fix it.

Here comes the second guide line we follow when design JustMock – there are no “right” or “wrong” choices. It is not white or black; rather it is like different gray shades. We could employ C# syntax in JustMock API to provide single method resolution (in most cases) but we didn’t. The reason is that different C# developers have different strategies to correct this issue. Here is a sample list with the most common fixes:

    // option 1
    mock.Setup(foo => foo.Bar((string)null)).Returns(1);

    // option 2
    mock.Setup(foo => foo.Bar(null as string)).Returns(1);

    // option 3
    mock.Setup(foo => foo.Bar(default(string))).Returns(1);

    // option 4
    string s = null;
    mock.Setup(foo => foo.Bar(s)).Returns(1);

After all, it’s matter of taste. Please notice that while I provided the sample above with Moq the issue is valid for JustMock. Lets make the things more interesting. Suppose we have the following concrete type:

    public sealed class Foo
    {
        public Foo() { ... }
        // ...
        private int Bar(string s) { ... }
        private int Bar(StringBuilder s) { ... }
    }

This time Bar(string s) and Bar(StringBuilder s) are private methods in a sealed type. Now we have to design an API for mocking private methods.

Note: Mocking private methods is a controversial thing. There are two equally large camps and a hot discussion between them. For good or bad, JustMock offers this feature.

We can provide the following method:

    public static void Arrange(object instance, string methodName, params object[] args) 
    { ... }

And then use it as follows:

    var foo = Mock.Create<Foo>();
    Mock.Arrange(foo, "Bar", null);

    string s = null;
    int actual = foo.Bar(s);

The problem with this approach is that the last argument passed to Arrange method is null and thus we cannot resolve the correct Bar(…) method. This time options 1 to 4 provided above don’t solve the issue. Lets see what can we do.

Approach 1: no method resolution

The problem is all about method resolution so if we don’t have to do it then we are good. Lets provide the API:

    public static void Arrange(object instance, MethodInfo method, params object[] args)
    { ... }

We have to change our test code:

    Type[] argTypes = { typeof(string) };
    var bar = typeof(Foo).GetMethod("Bar", argTypes);

    var foo = Mock.Create<Foo>();
    Mock.Arrange(foo, bar, null);

The test code is more messy. Now we have to deal with System.Reflection stuff which is not related to our code. Some developers are fine with this approach though. While this approach is suitable for API-to-API scenarios a lot of people prefer something more “friendly”.

Approach 2: pass method parameter types

We can pass the actual parameter types along with the parameter values. Lets change the Arrange method signature:

    public static void Arrange(object instance, string methodName, Type[] types, params object[] args) 
    { ... }

We added Type[] argument to Arrange method so we have to change our test code:

    var foo = Mock.Create<Foo>();
    Type[] argTypes = { typeof(string) };
    Mock.Arrange(foo, "Bar", argTypes, null);

    // use foo instance

This solution is easy to understand. It can also handle ref and out parameters and other more complex scenarios.

Approach 3: pass method parameter types as generic parameters

In case we decide to support private methods with simple signatures (no ref and out parameters and other fancy stuff) we can modify our previous approach by providing generic version of Arrange method (we can use T4 template for code generation; for the sake of simplicity we add a single generic parameter):

    public static void Arrange<T>(object instance, string methodName, params object[] args) 
    { ... }

We change our test code accordingly to:

    var foo = Mock.Create<Foo>();
    Mock.Arrange<string>(foo, "Bar", null);

    // use foo instance

This all looks good and nice but now we have to provide generic parameter types even when we don’t need them.

    var foo = Mock.Create<Foo>();
    Mock.Arrange<string>(foo, "Bar", "test");

    // use foo instance

It is not that bad but this can be annoying if Bar(…) method accepts, lets say, 5 integer parameters.

Approach 4: use typed references

The CLR and .NET framework already provide support for typed references but for our need we can come up with something much simpler. We have to provide support for our corner case when values are null. So we can provide a simple Null<T> type as follows:

    public sealed class Null<T>
        where T : class
    {
    }

Every time when we have to pass null value we are going to replace it with an instance of Null<T> type:

    var foo = Mock.Create<Foo>();
    Mock.Arrange(foo, "Bar", new Null<string>());

    // use foo instance

As the previous approach this one does not support methods with ref and out parameters. We can try to fix it by providing another constructor for Null<T> type:

    public sealed class Null<T>
        where T : class
    {
        public Null() {}

        public Null(System.Reflection.ParameterAttributes attrs)
        {
            this.Attrs = attrs;
        }

        public ParameterAttributes Attrs { get; private set; }
    }

Suppose we add the following method to Foo:

    private int Bar(ref string s) { ... }

If we want to mock it then our test code should like something like:

    var foo = Mock.Create<Foo>();
    Mock.Arrange(foo, "Bar", new Null<string>(ParameterAttributes.Out));

    // use foo instance

It doesn’t look nice to me. The syntax becomes more verbose and doesn’t flow naturally. We can mitigate it by adding new helper type as follows:

    public static class Arg
    {
        public static Null<T> Null<T>()
            where T : class
        {
            return new Null<T>();
        }
    }

Now we can compare the two options

    var foo = Mock.Create<Foo>();

    //option 1
    Mock.Arrange(foo, "Bar", new Null<string>());

    //option 2
    Mock.Arrange(foo, "Bar", Arg.Null<string>());

    // use foo instance

The readability seems a little bit better but many developers find the syntax verbose.

Approach 5: using dynamic (C# 4 and higher)

This is a good approach for a lot of developers. There is a caveat though. There are a plenty of customers that are still using .NET 3.5 and earlier. Shall we abandon them? A tough question.

Which one to use?

First, it is a wrong question. There is no silver bullet and the best thing we can do is to decide on a case-by-case basis. So far, we saw a few possible options; there are other alternatives as well. The options are not mutually exclusive which makes it even harder. If you are curious how we implemented it you can download a trial JustMock version.

NUI or GUI or … not

Today there are a lot of devices (smartphones, tablets, handheld game consoles, etc.) with support for gestural interface. We often call such interfaces natural user interfaces (NUI). These interfaces are in contrast with the traditional graphical user interfaces (GUI). In this post I am going to share my thoughts and experience with NUI.

Every software engineer knows that one should not make definitive assumptions how IT systems will be used. Often IT systems are used in unexpected and unpredicted ways. However such assumptions are rarely considered when it comes to user interfaces.

Natural user interfaces strive to offer more intuitive and easy human-technology interaction. This sounds all good and nice but lets focus on the word natural. In my understanding, natural means that the user doesn’t have to use artificial input/interaction devices such as keyboard and mouse. However, this does not mean that NUI is easy and intuitive for everyone. Users have still to learn it. While NUI is crucial for fast adoption of a new product it doesn’t mean it is easy to achieve it.

Today’s NUIs are not natural. Every company provides its own NUI standard and its per se artificial gestural language. Trying forcefully to apply NUI standard is not a solution. Cultural aspects should be preserved and considered. For example, almost every smartphone does not have support for left handed people.

My experience with different Android, iOS and Windows (Phone) 8 devices shows me that there is inconsistency between all of them. Often different applications for a particular platform use different gestures for the same command. Sometimes the companies use different NUI vocabularies for the same gesture. This could be confusing for the users.

In closing, I think that natural interfaces should allow us to interact with devices in the manner we interact with objects in everyday life. The devices should be able to learn user’s natural gestures/language and adapt to it. The companies should provide their natural interfaces as a fallback option.