MoqMeUp

Container that creates mocks for all the dependencies of a class.


Keywords
ioc, moq, tests, automocking, tdd, mocking, mock, di, dependency, injection
License
MIT
Install
Install-Package MoqMeUp -Version 1.0.5

Documentation

MoqMeUp

An easy to use ioc like container that mocks (using Moq) all the class dependencies.

Why

You probably saw/created a class like this right ?

public class UserService : IUserService
{
    private readonly IUserApiServices userApiServices;
    private readonly ICoolUserService coolUserService;
    private readonly ILogger logger;

    public UserService(
        IUserApiServices userApiServices,
        ICoolUserService coolUserService,
        ILogger logger)
    {
        this.userApiServices = userApiServices;
        this.coolUserService = coolUserService
        this.logger = logger;
    }

    public async Task<User> CreateUserAsync(CreateUserRequest r)
    {
        // All the magic code

        var createdUser = await this.userApiServices.CreateUserAsync(r);

        return createdUser;
    }
}

Normally in your tests you need to create the mocks by yourself in every test, doing that setup a lot of times, which is error prone. Then when you need to add new dependencies to a class, then you'll need to refactor all the tests to support the new dependency.

(ノಠ益ಠ)ノ彡┻━┻

[TestClass]
public class UserServiceTests
{
    [TestMethod]
    [ExpectedException(typeof(ApiException))]
    public async Task CreateUserAsync_WhenUserIsAlreadyRegistered_ShouldThrowApiException()
    {
        // Arrange 
        var userApiServicesMock = new Mock<IUserApiServices>();
        var coolUserApiServicesMock = new Mock<ICoolUserService>();
        var loggerMock = new Mock<ILogger>();
        
        userApiServicesMock.Setup(x => x.CreateUserAsync(It.IsAny<CreateUserRequest>())
            .ThrowsAsync(new ApiException("User is already registered"));
        
        var target = new UserService(
            userApiServicesMock.Object, 
            coolUserApiServicesMock.Object, 
            loggerMock.Object);
        
        // Act
        var act = await target.CreateUserAsync(new CreateUserRequest()
        {
            email = "sam@portugal.pt",
            password = "random"
        });
    }
}

Thats when MoqMeUp comes handy ◔ᴗ◔

How to use

  1. Install MoqMeUp via NuGet: NuGet

  2. There are two ways of using this package:

// Create a test class and make it inherit the MoqMeUp class:

[TestClass]
public class UserServiceTests : MoqMeUp<UserDataService>
{
    [TestMethod]
    [ExpectedException(typeof(ApiException))]
    public async Task CreateUserAsync_WhenUserIsAlreadyRegistered_ShouldThrowApiException()
    {
        // Arrange 
        this.Get<IApiServices>()
            .Setup(x => x.CreateUserAsync(It.IsAny<CreateUserRequest>())
            .ThrowsAsync(new ApiException("User is already registered"));

        var target = this.Build();

        // Act
        var act = await target.CreateUserAsync(new CreateUserRequest()
        {
            email = "sam@portugal.pt",
            password = "random"
        });
    }
}

Or

// Create a MoqMeUp Container and build the class that you want to test from it:

[TestClass]
public class UserServiceTests
{
    [TestMethod]
    [ExpectedException(typeof(ApiException))]
    public async Task CreateUserAsync_WhenUserIsAlreadyRegistered_ShouldThrowApiException()
    {
        var userServiceTestsMoqContainer = new MoqMeUp<UserDataService>();

        // Arrange 
        userServiceTestsMoqContainer.Get<IApiServices>()
            .Setup(x => x.CreateUserAsync(It.IsAny<CreateUserRequest>())
            .ThrowsAsync(new ApiException("User is already registered"));

        var target = userServiceTestsMoqContainer.Build();

        // Act
        var act = await target.CreateUserAsync(new CreateUserRequest()
        {
            email = "sam@portugal.pt",
            password = "random"
        });
    }
}

Features

Get

When there is only one dependency with that type you can use the Get to retrieve the mocked dependency.

public class UserService : IUserService
{
    private readonly IUserApiServices userApiServices;

    public UserService(IUserApiServices userApiServices)
    {
        this.userApiServices = userApiServices;
	}
	
    // The rest of the code goes here
}

[TestClass]
public class UserServiceTests : MockMeUp<UserService>
{
	public void GetUser_WhenUserExists_ShouldReturnIt()
	{
        this.Get<IUserApiServices>()
            .Setup(x => x.GetUser(1))
            .Returns(TestUsers.CoolUser);

        var target = this.Build();

        // The rest of the code goes here
	}
}

Get(string name)

When there is more than one dependency with that type you can use the Get(string name) to retrieve the mocked dependency.

public class UserService : IUserService
{
    private readonly IUserApiServices userApiServices;
    private readonly IUserApiServices userApiServicesTwo;

    public UserService(IUserApiServices userApiServices, IUserApiServices userApiServicesTwo)
    {
        this.userApiServices = userApiServices;
        this.userApiServicesTwo = userApiServicesTwo;
    }
	
    // The rest of the code goes here
}

[TestClass]
public class UserServiceTests : MockMeUp<UserService>
{
    public void GetUser_WhenUserExists_ShouldReturnIt()
    {
        this.Get<IUserApiServices>("userApiServices")
            .Setup(x => x.GetUser(1))
            .Returns(TestUsers.CoolUser);

        var target = this.Build();

        // The rest of the code goes here
    }
}

GetLazy()

When there is a lazy dependency, you can configure the mock of its value

public class UserService : IUserService
{
    private readonly Lazy<IUserApiServices> userApiServices;

    public UserService(Lazy<IUserApiServices> userApiServices)
    {
        this.userApiServices = userApiServices;
    }
	
	// The rest of the code goes here
}

[TestClass]
public class UserServiceTests : MockMeUp<UserService>
{
    public void GetUser_WhenUserExists_ShouldReturnIt()
    {
        this.GetLazy<IUserApiServices>()
            .Setup(x => x.GetUser(1))
            .Returns(TestUsers.CoolUser);

        var target = this.Build();

        // The rest of the code goes here
    }
}

GetLazy(string name)

Same as GetLazy(), but here you can specify the dependency name (if there is more than one, or because you want)

GetFunc()

When there is a func dependency, you can configure the mock of the result of the func

public class UserService : IUserService
{
    private readonly Func<IUserApiServices> userApiServices;

    public UserService(Func<IUserApiServices> userApiServices)
    {
        this.userApiServices = userApiServices;
    }
	
	// The rest of the code goes here
}

[TestClass]
public class UserServiceTests : MockMeUp<UserService>
{
    public void GetUser_WhenUserExists_ShouldReturnIt()
    {
        this.GetFunc<IUserApiServices>()
            .Setup(x => x.GetUser(1))
            .Returns(TestUsers.CoolUser);

        var target = this.Build();

        // The rest of the code goes here
    }
}

GetFunc(string name)

Same as GetFunc(), but here you can specify the dependency name (if there is more than one, or because you want)

Use(T dependency)

With Use you can define a custom value to the dependency, if you want to provide a dependency created by you. Thats a good way of configuring not mockable objects like integers etc.

public class UserService : IUserService
{
    private readonly IUserApiServices userApiServices;
    private readonly int int tenantId;

    public UserService(IUserApiServices userApiServices, int tenantId)
    {
        this.userApiServices = userApiServices;
        this.tenantId = tenantId;
    }
	
    // The rest of the code goes here
}

[TestClass]
public class UserServiceTests : MockMeUp<UserService>
{
    public void GetUser_WhenUserExists_ShouldReturnIt()
    {
        this.Get<IUserApiServices>()
            .Setup(x => x.GetUser(1))
            .Returns(TestUsers.CoolUser);

        this.Set<int>(20000);

        var target = this.Build();

        // The rest of the code goes here
	}
}

Use(string name, T dependency)

Same as Use(), but here you set manually a dependency for a specify the dependency by name

public class UserService : IUserService
{
    private readonly IUserApiServices userApiServices;
    private readonly int int tenantId;
    private readonly int int clientId;

    public UserService(IUserApiServices userApiServices, int tenantId, int clientId)
    {
        this.userApiServices = userApiServices;
        this.tenantId = tenantId;
        this.clientId = clientId;
    }
	
    // The rest of the code goes here
}

[TestClass]
public class UserServiceTests : MockMeUp<UserService>
{
    public void GetUser_WhenUserExists_ShouldReturnIt()
    {
        this.Get<IUserApiServices>()
            .Setup(x => x.GetUser(1))
            .Returns(TestUsers.CoolUser);
        
        this.Set<int>("tenantId", 20000);
        this.Set<int>("clientId", 1);
        
        var target = this.Build();
        
        // The rest of the code goes here
    }
}