Unit Testing in .NET Core with xUnit

In this post we see how to do unit testing in .NET Core with xUnit.

xUnit is a popular framework, with a lot of features and helpers to develop quickly our unit testings and implement them with a clean syntax; it’s very efficient and the result is that the tests execution is very fast.

In the previous post we implemented a  basic class with an in-memory DbContext, that we’ll use in the unit test.

The service

We can suppose that our sut is a service, like CategoryService.

The service has some methods to retrieve the category from the database with Entity Framework.

The service look like this:


public class CategoryService
{
readonly BlogContextFactory _contextFactory;

public CategoryService(BlogContextFactory contextFactory)
{
_contextFactory = contextFactory;
}

public IEnumerable<Category> GetCategories()
{
using (var db = _contextFactory.GetNewDbContext())
{
return db.Categories.OrderBy(c => c.Name).ToList();
}
}

public async Task<Category> AddCategory(Category category)
{
using (var db = _contextFactory.GetNewDbContext())
{
category.Id = Guid.NewGuid();

await db.Categories.AddAsync(category);
await db.SaveChangesAsync();

return category;
}
}

public async Task UpdateCategory(Category category)
{
using (var db = _contextFactory.GetNewDbContext())
{
db.Categories.Update(category);
await db.SaveChangesAsync();
}
}

public async Task DeleteCategory(Category category)
{
using (var db = _contextFactory.GetNewDbContext())
{
db.Categories.Remove(category);
await db.SaveChangesAsync();
}
}
}

Unit Test class

Now we can implement the Unit Test class; we can use the base class DatabaseFixture and pass the context factory configured with an in-memory DbContext to the service:


public class CategoryServiceTests : DatabaseFixture
{
readonly CategoryService _categoryService;

public CategoryServiceTests() : base("CategoryContext")
{
_categoryService = new CategoryService(ContextFactory);
}

[Fact]
public void should_return_categories_list()
{
var categories = _categoryService.GetCategories();
categories.Should().NotBeNullOrEmpty();
categories.Count().Should().BeGreaterThan(0);
}

[Fact]
public async Task should_add_new_category()
{
var category = new Category()
{
Id = new Guid("{1225FE5B-9C46-4BA3-9233-9337DDC5F478}"),
Name = "Test Category"
};

category = await _categoryService.AddCategory(category);

using (var db = ContextFactory.GetNewDbContext())
{
var newCategory = await db.FindAsync<Category>(category.Id);
newCategory.Should().NotBeNull();
}
}

[Fact]
public async Task should_edit_category()
{
using (var db = ContextFactory.GetNewDbContext())
{
var category = await db.FindAsync<Category>(new Guid("{BE7EB1E1-FB67-4FE1-A96E-4721D37AFE29}"));
category.Name = "category modified";
await _categoryService.UpdateCategory(category);

category = await db.FindAsync<Category>(new Guid("{BE7EB1E1-FB67-4FE1-A96E-4721D37AFE29}"));
category.Name.ShouldBeEquivalentTo("category modified");
}
}

[Fact]
public async Task should_delete_category()
{
var category = new Category() { Id = new Guid("{5D134CF2-EF37-4663-B3D2-64F2E3DBF3BE}"), Name = "Category1" };
await _categoryService.DeleteCategory(category);

using (var db = ContextFactory.GetNewDbContext())
{
category = await db.FindAsync<Category>(new Guid("{5D134CF2-EF37-4663-B3D2-64F2E3DBF3BE}"));
category.Should().BeNull();
}
}
}

The Fact attribute is the xUnit attribute used for the test methods.

As discussed above the ContextFactory is configured to returns an instance in-memory of the DbContext.

Now we can run the unit test by opening a command console, going to the UnitTest project folder and running the command:

dotnet test

The command will run the tests and will show us the results.

You can find the source code here.

 

Advertisements
Unit Testing in .NET Core with xUnit

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s