A Cleaner Way to Create Mocks in .NET

[Fact]
public void Login_With_Success_Returns_User
{
//Arrange
var userId = Guid.NewGuid();
var username = "foo";
var password = "bar";
var user = new User { Id = userId };
var mockUserService = new Mock<IUserService>();

mockUserService.Setup(x => x.Authenticate(
It.Is<string>(i => i == username),
It.Is<string>(i => i == password)
)).Returns(userId);

mockUserService.Setup(x => x.GetUserById(
It.Is<Guid>(i => i == userId),
)).Returns(user);
//Act
var loginController = new LoginController(mockUserService.Object);
var output = loginController.Login(username, password);
//Assert
Assert.Equal(output, user);
mockUserService.VerifyAll();
}

Take 1: Factory pattern

public static class UserServiceMocks
{
public static Mock<IUserService> MockAuthenticateAndGetUserById(string username, string password, Guid userId, User output)
{
var mock = new Mock<IUserService>();

mock.Setup(x => x.Authenticate(
It.Is<string>(i => i == username),
It.Is<string>(i => i == password)
)).Returns(userId);

mock.Setup(x => x.GetUserById(
It.Is<Guid>(i => i == userId),
)).Returns(output);

return mock;
}
}

Take 2: Inheritance

public class MockUserService : Mock<IUserService>
{
public void MockAuthenticate(string username, string password, Guid output)
{
Setup(x => x.Authenticate(
It.Is<string>(i => i == username),
It.Is<string>(i => i == password)
)).Returns(output);
}
public void MockGetUserById(Guid userId, User output)
{
Setup(x => x.GetUserById(
It.Is<Guid>(i => i == userId),
)).Returns(output);
}
}
[Fact]
public void Login_With_Success_Returns_User
{
//Arrange
var userId = Guid.NewGuid();
var username = "foo";
var password = "bar";
var user = new User { Id = userId };
var mockUserService = new MockUserService();
mockUserService.MockAuthenticate(username, password, output: userId);
mockUserService.MockGetUserById(userId, output: user);
//Act
var loginController = new LoginController(mockUserService.Object);
var output = loginController.Login(username, password);
//Assert
Assert.Equal(output, user);
mockUserService.VerifyAll();
}

Take 3: Fluent API

public class MockUserService : Mock<IUserService>
{
public MockUserService MockAuthenticate(string username, string password, Guid output)
{
Setup(x => x.Authenticate(
It.Is<string>(i => i == username),
It.Is<string>(i => i == password)
)).Returns(output);
return this;
}
public MockUserService MockGetUserById(Guid userId, User output)
{
Setup(x => x.GetUserById(
It.Is<Guid>(i => i == userId),
)).Returns(output);
return this;
}
}
[Fact]
public void Login_With_Success_Returns_User
{
//Arrange
var userId = Guid.NewGuid();
var username = "foo";
var password = "bar";
var user = new User { Id = userId };
var mockUserService = new MockUserService()
.MockAuthenticate(username, password, output: false)
.MockGetUserById(userId, output: user);
//Act
var loginController = new LoginController(mockUserService.Object);
var output = loginController.Login(username, password);
//Assert
Assert.Equal(output, user);
mockUserService.VerifyAll();
}

--

--

--

Organizer, Flutter NYC

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Live Chat Plugins For WordPress Website

Input ID array. This sentence only contained a single

How to Get Data From Telegram Using Python

Trending Repositories of June on GitHub

No more Git Config

How To Migrate From Magento To PrestaShop In Three Simple Steps

Magento To PrestaShop Migration

What makes OSYS different?

Zeedex v0.3.0 — The Origin

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Martin Rybak

Martin Rybak

Organizer, Flutter NYC

More from Medium

Create well designed application with Unified Identity

Observer Pattern

The Simple Guide to Porting C# Code for RestSharp Next v107 and Beyond

Array or Linkedlist, or custom data type?