http://blogs.clariusconsulting.net/kzu

Daniel Cazzulino's Blog

Go Back to
kzu′s Latest post

How to mock extension methods

. without paying for a TypeMock Isolator license to do it ;-)

There’s going to be no magic here. You have to explicitly design for testability. That’s one of the things I like about mocking: if you can mock a dependency, then it means your design is loosely coupled (e.g. not tied to a particular implementation of that dependency), and you’re not "cheating or taking any shortcuts. If a test can replace a dependency at test-time, your’ll surely be able to replace the real implementation with something different when/if time comes to do so.

Extension methods are tricky because they are static methods, really just syntactic sugar for a "good" old static class with static methods (typically a "helper" of some sort. But what is special about them, is that they show up (provided you have the right usings/imports) in the target type API as if they were its own instance methods. This is significant, because it also means that it’s very easy to pollute the target type API as you (and other referenced libraries) keep piling up these methods on it.

I therefore prefer an approach where you group your extensions under a single API, and access that API via a single extension method on the target type that becomes the entry point to your extensions. For example, say you have an IPerson interface, and you want to add secutity-related helper methods that you can use consistently from other logic or services. One way of adding a GetPermissions security helper extension method (that will get the rights of the user over a given resource, for example), would be to plug it right into IPerson as an extension method:

[Flags]
public enum Permissions
{
    Read = 0,
    Modify = 1,
    Delete = 2,
    FullControl = Read | Modify | Delete
}

public static class SecurityExtensions
{
    public static Permissions GetPermissions(this IPerson person, Uri resource)
    {
        // get permissions for the given resource from somewhere
    }
}

This would get you the API right on the IPerson object:

image

If you go overboard with this "extension in the root" approach, you might end up with an ugly looking assorted collection of helpers attached to the main class, such as what happened to the UML APIs in Visual Studio 2010. Look at the before and after we reference and import the assembly containing the extensions to IClass (the interface that represents a class in a UML Logical Class Diagram):

image

After referencing Microsoft.VisualStudio.Uml.Extensions.dll Microsoft.VisualStudio.ArchitectureTools.Extensibility.dll (it’s in PublicAssemblies) and adding the corresponding using/import Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml:

image

(I pasted together a couple more pages of intellisense for added effect, but you see the point, rigth? The original API totally buried in a sea of extension methods?)

Extension Interfaces

Another alternative is to group extension methods that provide related functionality under what I’d extension interfaces. In our person example, we might find out that the security-related methods start growing, and we’d like to keep the main API clean, so we introduce the ISecurity extension interface, and provide an extension method that is the entry point to it:

public interface ISecurity
{
    Permissions GetPermissions(Uri resource);
}

public static class SecurityExtensions
{
    public static ISecurity Security(this IPerson person)
    {
        throw new NotImplementedException();
    }
}

Now, the consumer of the IPerson object can see that there is security-related behavior available to him, but won’t see what those are unless he needs to:

image

Typically, the SecurityExtensions class will instantiate a non-public implementation of ISecurity that does the real work, passing the person to work on as a constructor argument:

internal class Security : ISecurity
{
    private IPerson person;

    public Security(IPerson person)
    {
        this.person = person;
    }

    public Permissions GetPermissions(Uri resource)
    {
        // get the real permissions for the person
        // field we have received, for the given resource
        throw new NotImplementedException();
    }
}

public static class SecurityExtensions
{
    public static ISecurity Security(this IPerson person)
    {
        return new Security(person);
    }
}

The attentive reader might have noticed that, being a regular interface, the extension interface now can expose properties where it makes sense, overcoming the lack of support for extension properties in C#. For example we could add a Roles property quite easily:

image

And because the extension interface is nothing more than a fluent interface in the end, you can use the trick I blogged about before to hide those pesky System.Object members:

image

How to mock extension methods, again?

Back to the testing subject, in order to test the Update method above, we’ll need to replace the ISecurity implementation, right? Because we followed the extension interface design approach, we now have a single extension method to replace, the one that creates the default implementation of the ISecurity inteface. And if you look at that method, all it is being a factory for creating an implementation of ISecurity given an IPerson:

public static class SecurityExtensions
{
    public static ISecurity Security(this IPerson person)
    {
        return new Security(person);
    }
}

So for testing purposes we can just add an internal factory that will isolate the extension method behavior, and that we’ll replace for testing purposes:

public static class SecurityExtensions
{
    internal static Func<IPerson, ISecurity> SecurityFactory = person => new Security(person);

    public static ISecurity Security(this IPerson person)
    {
        return SecurityFactory(person);
    }
}

The test for the Update method above, which will have internals visibility enabled from the project under test, will simply replace the factory with one that returns a mock:

public void WhenPersonHasNoModifyPermission_ThenThrowsSecurityException()
{
    var security = new Mock<ISecurity>();
    security.Setup(x => x.GetPermissions(It.IsAny<Uri>())).Returns(Permissions.Read);

    SecurityExtensions.SecurityFactory = person => security.Object;

    var controller = new DocumentsController();

    Assert.Throws<SecurityException>(() =>
        controller.Update(new Mock<IPerson>().Object, new Uri("http://foo")));
}

And voila! We have just passed a test where the class under test uses an extension method:

public class DocumentsController
{
    public void Update(IPerson person, Uri document)
    {
        if (!person.Security().GetPermissions(document).HasFlag(Permissions.Modify))
            throw new SecurityException();

        // ...

Also note that the intenal Security class that implements ISecurity can also be fully tested in isolation.

Happy moqing!

PS: remember the focus of this post is on mocking extension methods, not on how to design security for your domain ;-) . Feel free to mentally replace ISecurity with IFoo, GetPermissions with DoSomething, etc., as needed.

Comments

14 Comments

  1. Thanks for this article, it’s very helpful for moqing my own extensions.

    What I was trying to moq, though, is something I don’t control directly. I’ve got an app using EF CodeFirst, accessing the DbContext via interfaces in a Repository. The issue is that since I am using a lot of the IDbSet functionality in my repositories (e.g. Includes, Attach, etc), my wrapper interface for the DbContext exposes IDbSets.

    Problem arises is that the Include method on there is an extension, and when I try and use it against a mocked context, it winds up returning a null set. I’d rather not have to rewrite everything to cope (especially since it works fine as-is in production). Is there any way to override the behavior or the extension method in this case?

  2. [...] CazzulinoData MVP(a.k.a. KZU)Dev Lead @ ClariusBuenos Aires – Argentina    I got this question a couple times already so I’ll save keystrokes and post [...]

  3. [...] Aires – Argentina    You probably know I’m an advocate of a particular way of doing extension methods that I call the “Extension Method Entry Point Pattern”, which makes it easier to mock [...]

  4. [...] This post was Twitted by NickJosevski [...]

  5. Very good.

    But it leaves a doubt. if I want mock an extension method (for a interface) but the test I use the concrete class.

    Something like this: http://stackoverflow.com/questions/12760930/mock-extension-methods-as-an-interface

  6. As extension methods are merely syntactical sugar, in many cases sweetness of it will decrease when using such approach. It might be hard to create reasonable abstraction for the interface.

    Anyway it’s good to be aware of such option, thank you.

  7. Good article, you helped us a lot!

    For our problem, we decided to inject your IScurity into the constructor of the DocumentsController and use it’s GetPermissions() method directly in the DocumentsController .Update() method.

    This way yo don’t need the SecurityExtensions class and the test it’s more intuitive, (you don’t need to assign lambda expressions to a static class property) and anyway you can mock ISecurity in the clasic way.

    Thanks!

  8. In most cases I have abandoned extensions methods in favor of interface classes and dependency injection. With DI, unit testing is simpler and cleaner and your tests are more conclusive.

    • And said interfaces become humongous collection of usability overloads that when you have to implement the interface, you don’t know which of the 25 members is the “real” one ;)

  9. Thanks for this post, I’ve found this to be a method I’ve reused in a number of places. We do use interfaces, DI and IOC but there’s some places where extension methods are just neater and more appropriate. In these cases it’s great that this method is available to enable us to use extension methods in a testable way.

    There’s one modification to this method that I commonly use that I’d like to share.
    Instead of using internal accessibility on the factory (which doesn’t feel like a very nice thing to do just to make something testable) I’ve set the factory to private and have been using reflection to set the factory instead.

    I’ve achieved this using the following lines in the test:
    Func lamda = person => security.Object;
    typeof(SecurityExtensions).GetField(“securityFactory”, BindingFlags.Static | BindingFlags.NonPublic).SetValue(null, lamda);

    Instead of: SecurityExtensions.SecurityFactory = person => security.Object;

    • Sorry I’ve just seen a small typo in what I copied in, that should be:
      Func securityFactory = person => security.Object;
      typeof(SecurityExtensions).GetField(“securityFactory”, BindingFlags.Static | BindingFlags.NonPublic).SetValue(null, securityFactory);

    • ok no typo, the original was fine, if I could delete or amend one of my comments here I would

  10. [...] (old) post on how to mock extension methods helped me get my code [...]