Unit Testing .NET Core

Introduction

With the recent arrival of .NET Core, some things that we were used to having are no longer available. This includes unit tests – plus Visual Studio integration – and mocking frameworks. Fortunately, they are now becoming available, even if, in some cases, in pre-release form.

In this post, I will cover:

  • Unit testing frameworks
  • Mocking libraries
  • Validation libraries

I won’t explore everything that exists, just present a simple setup that works well for .NET Core.

Unit Testing

So, you want to do unit testing? There are a couple of frameworks for that purpose that work with .NET Core, which include:

MS Test is Microsoft’s own unit testing library, I’d say a much hated one because of its historical tie to Visual Studio. This was the last one that was announced for .NET Core and it’s still not in release form.

They more or less work the same way, so let’s see how to use xUnit, my favorite one So, you need to add two Nuget packages:

  • xunit: this is the actual library that you will be using
  • dotnet-test-xunit: this is the runner and integration with Visual Studio

I sometimes have a base class for tests, which takes care of loading configuration and initializing stuff, but let’s leave that aside. A unit test class for xUnit looks like this:

using Xunit;

public class MyTests
{
[Fact]
public void Test()
{
}
}

Now, you need to configure the runner so that you can run tests in Visual Studio. Using project.json, it goes like this:

{
"version": "1.0.0-*",
"testRunner": "xunit",
"buildOptions": {
"emitEntryPoint": false,
"copyToOutput": ["appsettings.json"]
},

"dependencies": {
"dotnet-test-xunit": "2.2.0-preview2-build1029",
"Microsoft.Extensions.Configuration": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.PlatformAbstractions": "1.0.0",
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
},
"xunit": "2.2.0-beta2-build3300"
},

"frameworks": {
"netcoreapp1.0": {
"imports": "dnxcore50"
}
}
}

Notice that I am copying to the output folder the appsettings.json file, I am not going to talk about it, but let’s just say that it has some configuration that my tests will use, and it needs to be on the same file as the unit tests assembly.

With the Visual Studio integration working, we get this:

image

So we can run and debug our tests directly from here. Nice to have coherent behavior for all unit test frameworks!

Mocking

As for mocking, there are also some mocking frameworks that work with .NET Core:

I’ll pick Moq for this exercise. Just add the Moq package to your project. Here’s how to do simple mocking of an interface:

using Xunit;
using Moq;

[Fact]
public void Test()
{
var mock = new Mock<IService>();
mock
.Setup(x => x.Get())
.Returns("Hi there!");

var svc = mock.Object;

var result = svc.Get();

Assert.NotNull(result);

Assert.Equal("Hi there!", result);
}

Exactly the same as you’d do in a classic .NET unit test using mocking.

Validation

As for validations, I know of two libraries that work with .NET Core:

I’ll pick FluentAssertions. Here’s a simple example, for the same test:

using FluentAssertions;
using Moq;
using Xunit;

[Fact]
public void Test()
{
var mock = new Mock<IService>();
mock
.Setup(x => x.Get())
.Returns("Hi there!");

var svc = mock.Object;

var result = svc.Get();

result
.Should()
.BeOfType<string>()
.And
.Be("Hi there!");
}

Again, this should be familiar to everyone.

Conclusion

So, it’s no longer unit tests holding us back from .NET Core! Most of what is done today in classic .NET can be done in Core by now. There are still some more complex libraries, for interception, mapping, serialization, etc, that are not quite there yet, but I expect these to come with time.