Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET infrastructure in MediatR handlers

I prefer to keep my handlers free from ASP.NET infrastructure that is very hard to test (yes, even in ASP.NET Core). But sometimes it happens and you have a dependency like UserManager (I'd like to know one day why it's not an interface), HttpContext, etc. and unit-tests are turned into a mocking-hell.

I tried using integration testing to deal with it by creating a TestServer and having all the ASP.NET infrastructure initialized for every api call. It works quite well but sometimes seems like an overkill if I want to test simple logic of my handler. And while it solves technical problem of mocking ASP.NET infrastructure, it keeps architectural problem (if you consider it so) of having ASP.NET infrastructure into your handlers.

I'd like to know what are the recommended approaches to deal with it?

like image 815
SiberianGuy Avatar asked Jan 30 '17 08:01

SiberianGuy


People also ask

What is MediatR .NET core?

MediatR Requests are very simple request-response style messages, where a single request is synchronously handled by a single handler (synchronous from the request point of view, not C# internal async/await). Good use cases here would be returning something from a database or updating a database.

What is the benefit of MediatR?

MediatR provides you with other functionality as well. It supports notifications mechanism. It may be very useful if you use domain events in your architecture. All classes of your events must implement INotification marker interface.

Is MediatR asynchronous?

Because MediatR syncs all notifications in a row, it means that if notifications are slow, the request stays open until it's done. Perform IO tasks async and Parallel. We have the ability to execute Notifications the way we want with a little change.


1 Answers

I feel your pain. I stumbled across a fantastic blog post from Jimmy Bogard that handles this problem by using what Martin Fowler calls Subcutaneous Tests. I will leave the deep explanation to those experts but in a nutshell subcutaneous tests simply avoid all the difficult to test aspects of the UI.

Shameless plug: I am currently in the process of writing up a wiki that demonstrates these patterns in a sample end-to-end project on github. It's not difficult to follow but is probably too much code to post for a SO answer.

To Summarize:

  • If you are using MediatR correctly your controllers should be very thin which makes testing them pointless.
  • What you want to test are your handlers.
  • However, you want to test your handlers as part of your real world pipeline.

To Solve:

  1. Wrap the http request in a transaction.
  2. Build a test fixture that mimics the applications Startup.cs
  3. Setup a test db server to execute queries and commands against but also is reset after each test.

That's basically it. Everytime you run an integration test against one of your handlers:

  • The hosting environment is mocked but your application is started up in a real world test.
  • Your query or command is wrapped in a transaction mimicking your DbContext.
  • The handler is executed against a real database and then reset.

I would add more code examples to my answer but between the blog post and the wiki I provided, it is much easier to follow the code examples there.

Edit 8/2021:

Stick with the source. Jimmy Bogard keeps the contoso university project current on his github page. Another great and a little more advanced example is the modular monolith project by Kamil Grzybek. That also is updated regularly on his github page.

like image 156
trevorc Avatar answered Sep 27 '22 20:09

trevorc