In acceptance or integration tests of your .NET application, you probably want to mock external HTTP services so you can focus on testing your implemented logic. For this purpose, you might want to mock your HttpClient or its HttpMessageHandler, which is only a partial solution as it does not run HTTP over the wire. Or you can spin off Docker containers that will return responses you configured beforehand using some API, which requires a lot of boilerplate code and cannot be parallelized well.
MockH is a small library that allows you to do both - run real HTTP requests and configure the responses in code, directly within your test. As it is designed to have no side effects, it can run in parallel and does not mess with ASP.NET Core in any way.
MockH is powered by GenHTTP, a lightweight and fully managed HTTP server framework written in .NET. This allows you to use high-level features such as JSON serialization to reduce boiler plate code required in your tests. Additionally, it can also be used in combination with any testing framework.
The following, minimal example will show you how to spin up a server instance and how to consume it in your code:
using MockH;
[TestMethod]
public async Task TestSomething() 
{
   // start a HTTP server listening on a random, free port
   // servicing the endpoints you define here
   await using var server = await MockServer.RunAsync
   (
       On.Get("/users/1").Return(new User(...)),
       On.Get("/users/2").Respond(ResponseStatus.NoContent)
   );
   // obtain the URL from the server instance to use
   // it in your code as needed
   var url = server.Url();
   // execute your tests here
}
MockH supports various kind of rules that can be passed to RunAsync() to generate your responses:
// return a specific status code
On.Get("/ifail").Respond(ResponseStatus.InternalServerError);
// redirect the client
On.Get().Redirect("https://github.com");
// execute logic and return some simple text value
On.Get().Run(() => "42");
// execute logic and return some JSON
private record MyClass(int IntValue, string StringValue);
On.Get().Run(() => new MyClass(42, "The answer"));
// execute logic asynchronously
On.Get().Run(async () => await ...);
// access query parameters (GET /increment?=1)
On.Get("/increment").Run((int i) => i + 1);
// access path parameters (GET /increment/1)
On.Get("/increment/:i").Run((int i) => i + 1);
// access request body
On.Post().Run((MyClass body) => body);
// access request body as stream
On.Post().Run((Stream body) => body.Length);
With MockH, you can write expressive, parallelizable, and fully isolated integration tests that use real HTTP without complex infrastructure.
Check out the MockH GitHub repository for more examples and advanced features.
Cover picture by Phil Harvey
              
    
Top comments (0)