×

iFour Logo

Unit testing a custom middleware in ASP.NET Core with Interface

Kapil Panchal - October 21, 2020

Listening is fun too.

Straighten your back and cherish with coffee - PLAY !

  • play
  • pause
  • pause
Unit testing a custom middleware in ASP.NET Core with Interface

What is unit test?


A unit test is a type of testing.It is the Small Part of code that can be logically in a Program and test that code is work properly that is testing.

The latest versions of unit testing can be found in frameworks like JUnit, or testing tools like Test Complete. You will also find SUnit, which is the mother of all unit testing frameworks it is created by Kent Back.

How does the tests look like?


A unit can be almost anything you want it is, a line of code or a method, and a class. Smaller tests give you a more detail view of how your code is performing. There is also the practical aspect that when you test very small units, your tests can be run fast; like so many tests in a second fast.

Consider this sample code

 
def divider (x, y)
return x/y
End
		   

This example is simple, but it gives you an idea of what I mean by small. Small tests also have the benefit of building it harder to cross-systems from code into a database, or 3rd party system. There is not anything wrong with crossing systems, but there is a result like gradually slowing your tests, a test suite that takes hours to run.

What is Middleware?


Middleware’s are a fundamental part of an ASP.NET application, introduced from day one. They are executed in the order they are added on every request and could be considered similar to the HTTP Handlers and HTTP Modules of the classic ASP.NET. Since middleware’s can execute code before or after calling subsequent within the pipeline, they're considered ideal for plenty of varied application features, including exception handling, logging, authentication, etc.

Middleware is often tested in isolation with Test Server. It allows you to instantiate an app pipeline containing only the components that you simply got to test.

Advantages of Middleware


  • Requests are sent in-memory instead of being serialized over the network.
  • Exceptions within the middleware can flow directly back to the calling test.
  • It's possible to customize server data structures, like HttpContext, directly within the test.

Middleware’s offer a more powerful and flexible solution and for that, they need to be tested! Thankfully there's how to try to that so let's first see what we are getting to test then just get in there to Example:

You can need to Install Microsoft.AspNetCore.Testhst

First of All, you can need to Configure the processing pipeline to use the middleware for the test. part of program configure Processing pipeline is shown below.

 
[Fact]
public async Task MiddlewareTest_ReturnsNotFoundForRequest()
 {
using varhst = await new hstBuilder().ConfigureWebhst(webBuilder =>
 {
webBuilder.UseTestServer().ConfigureServices(services =>
 {
services.AddMyServices();
 })
.Configure(app =>
 {
app.UseMiddleware();
  });
  })
.StartAsync();
}

After that you need to send requests with the HttpClient sample code is below.


[Fact]
 public async Task MiddlewareTest_ReturnsNotFoundForRequest()
 {
using varhst = await new hstBuilder().ConfigureWebhst(webBuilder =>
 {
webBuilder.UseTestServer().ConfigureServices(services =>
 {
services.AddMyServices();
 })
.Configure(app =>
 {
app.UseMiddleware();
 });
 })
.StartAsync();
var response = await hst.GetTestClient().GetAsync("/");
}

Assert the result and make an assertion of the opposite of the result that you expect. An embryonic run with a false positive assertion confirms that the test fails. when the middleware is performing Truly. Start test and confirm that the test is failed.

In this example, the middleware returns a 404-status code which is NOT FOUND code when the root endpoint is requested. Make the first one test run with Assert.NotEqual (); which should be fail.

 
[Fact]
public async Task MiddlewareTest_ReturnsNotFoundForRequest()
 {
using varhst = await new hstBuilder().ConfigureWebhst(webBuilder =>
 {
webBuilder.UseTestServer().ConfigureServices(services =>
 {
services.AddMyServices();
 })
.Configure(app =>
 {
app.UseMiddleware();
 });
 })
.StartAsync();
var response = await hst.GetTestClient().GetAsync("/");
Assert.NotEqual(HttpStatusCode.NotFound, response.StatusCode);
 }

Change the assertion for test the middleware under normal operating ambiance. The final test uses Assert.Equal( );. Run the test a second time to confirm that it was successful.

 
[Fact]
public async Task MiddlewareTest_ReturnsNotFoundForRequest()
  {
using varhst = await new hstBuilder()
.ConfigureWebhst(webBuilder =>
  {
webBuilder.UseTestServer().ConfigureServices(services =>
  {
services.AddMyServices();
  })
.Configure(app =>
  {
app.UseMiddleware();
  });
  })
.StartAsync();
var response = await hst.GetTestClient().GetAsync("/");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}

Looking to Hire Dedicated .ASP.Net Core Developer ? Contact Now.

Send requests with HttpContext


A test app is also sending a request using SendAsync(Action, CancellationToken). In this example, several checks are made when https:// example. com/A/Path/?and=query is done by the middleware.

 
[Fact]
public async Task TestMiddleware_ExpectedResponse()
 {
using varhst = await new hstBuilder()
.ConfigureWebhst(webBuilder =>
 {
webBuilder.UseTestServer().ConfigureServices(services =>
 {
services.AddMyServices();
 })
.Configure(app =>
 {
app.UseMiddleware();
 });
 })
.StartAsync();
var server = hst.GetTestServer();
server.BaseAddress = new Uri("https://example.com/A/Path/");
var context = await server.SendAsync(c =>
 {
c.Request.Method = HttpMethods.Post;
c.Request.Path = "/and/file.txt";
c.Request.QueryString = new QueryString("?and=query");
 });
Assert.True(context.RequestAborted.CanBeCanceled);
Assert.Equal(HttpProtocol.Http11, context.Request.Protocol);
Assert.Equal("POST", context.Request.Method);
Assert.Equal("https", context.Request.Scheme);
Assert.Equal("example.com", context.Request.hst.Value);
Assert.Equal("/A/Path", context.Request.PathBase.Value);
Assert.Equal("/and/file.txt", context.Request.Path.Value);
Assert.Equal("?and=query", context.Request.QueryString.Value);
Assert.NotNull(context.Request.Body);
Assert.NotNull(context.Request.Headers);
Assert.NotNull(context.Response.Headers);
Assert.NotNull(context.Response.Body);
Assert.Equal(404, context.Response.StatusCode);
Assert.Null(context.Features.Get().ReasonPhrase);
 }

SendAsync allow the direct configuration of an HttpContext object instead of using the HttpClient abstractions. Use SendAsync to control structures only available on the server, like HttpContext.Items or HttpContext.Features.

As with the Previous example that tested for a 404 - Not Found response, check the other for every assert statement within the preceding test. The check confirms that the test fails correctly when the middleware is working normally. After you've confirmed that the false-positive test works, set the ultimate assert statements for the expected conditions and values of the test. Run it again to verify that the test passes.

Conclusion


Using Middleware unit testing you can test parts of code which is placed in program. You can also get more detail result of your testing. Using these you can customize data structures, like HttpContext, directly within the test. You can test from both sides correct or wrong.We hope this blog will be helpful for you to understand concept of unit testing a custom middleware in ASP.NET Core.

Unit testing a custom middleware in ASP.NET Core with Interface Table of Content 1.What is unit test? 2.How does the tests look like? 3.What is Middleware? 4.Advantages of Middleware 5.Send requests with HttpContext 6.Conclusion What is unit test? A unit test is a type of testing.It is the Small Part of code that can be logically in a Program and test that code is work properly that is testing. The latest versions of unit testing can be found in frameworks like JUnit, or testing tools like Test Complete. You will also find SUnit, which is the mother of all unit testing frameworks it is created by Kent Back. How does the tests look like? A unit can be almost anything you want it is, a line of code or a method, and a class. Smaller tests give you a more detail view of how your code is performing. There is also the practical aspect that when you test very small units, your tests can be run fast; like so many tests in a second fast. Consider this sample code   def divider (x, y) return x/y End This example is simple, but it gives you an idea of what I mean by small. Small tests also have the benefit of building it harder to cross-systems from code into a database, or 3rd party system. There is not anything wrong with crossing systems, but there is a result like gradually slowing your tests, a test suite that takes hours to run. What is Middleware? Middleware’s are a fundamental part of an ASP.NET application, introduced from day one. They are executed in the order they are added on every request and could be considered similar to the HTTP Handlers and HTTP Modules of the classic ASP.NET. Since middleware’s can execute code before or after calling subsequent within the pipeline, they're considered ideal for plenty of varied application features, including exception handling, logging, authentication, etc. Read More: Ultimate Guide For Implementing Repository Pattern And Unit Of Work For .net Core Middleware is often tested in isolation with Test Server. It allows you to instantiate an app pipeline containing only the components that you simply got to test. Advantages of Middleware Requests are sent in-memory instead of being serialized over the network. Exceptions within the middleware can flow directly back to the calling test. It's possible to customize server data structures, like HttpContext, directly within the test. Middleware’s offer a more powerful and flexible solution and for that, they need to be tested! Thankfully there's how to try to that so let's first see what we are getting to test then just get in there to Example: You can need to Install Microsoft.AspNetCore.Testhst First of All, you can need to Configure the processing pipeline to use the middleware for the test. part of program configure Processing pipeline is shown below.   [Fact] public async Task MiddlewareTest_ReturnsNotFoundForRequest() { using varhst = await new hstBuilder().ConfigureWebhst(webBuilder => { webBuilder.UseTestServer().ConfigureServices(services => { services.AddMyServices(); }) .Configure(app => { app.UseMiddleware(); }); }) .StartAsync(); } After that you need to send requests with the HttpClient sample code is below. [Fact] public async Task MiddlewareTest_ReturnsNotFoundForRequest() { using varhst = await new hstBuilder().ConfigureWebhst(webBuilder => { webBuilder.UseTestServer().ConfigureServices(services => { services.AddMyServices(); }) .Configure(app => { app.UseMiddleware(); }); }) .StartAsync(); var response = await hst.GetTestClient().GetAsync("/"); } Assert the result and make an assertion of the opposite of the result that you expect. An embryonic run with a false positive assertion confirms that the test fails. when the middleware is performing Truly. Start test and confirm that the test is failed. In this example, the middleware returns a 404-status code which is NOT FOUND code when the root endpoint is requested. Make the first one test run with Assert.NotEqual (); which should be fail.   [Fact] public async Task MiddlewareTest_ReturnsNotFoundForRequest() { using varhst = await new hstBuilder().ConfigureWebhst(webBuilder => { webBuilder.UseTestServer().ConfigureServices(services => { services.AddMyServices(); }) .Configure(app => { app.UseMiddleware(); }); }) .StartAsync(); var response = await hst.GetTestClient().GetAsync("/"); Assert.NotEqual(HttpStatusCode.NotFound, response.StatusCode); } Change the assertion for test the middleware under normal operating ambiance. The final test uses Assert.Equal( );. Run the test a second time to confirm that it was successful.   [Fact] public async Task MiddlewareTest_ReturnsNotFoundForRequest() { using varhst = await new hstBuilder() .ConfigureWebhst(webBuilder => { webBuilder.UseTestServer().ConfigureServices(services => { services.AddMyServices(); }) .Configure(app => { app.UseMiddleware(); }); }) .StartAsync(); var response = await hst.GetTestClient().GetAsync("/"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } Looking to Hire Dedicated .ASP.Net Core Developer ? Contact Now. SEE HERE Send requests with HttpContext A test app is also sending a request using SendAsync(Action, CancellationToken). In this example, several checks are made when https:// example. com/A/Path/?and=query is done by the middleware.   [Fact] public async Task TestMiddleware_ExpectedResponse() { using varhst = await new hstBuilder() .ConfigureWebhst(webBuilder => { webBuilder.UseTestServer().ConfigureServices(services => { services.AddMyServices(); }) .Configure(app => { app.UseMiddleware(); }); }) .StartAsync(); var server = hst.GetTestServer(); server.BaseAddress = new Uri("https://example.com/A/Path/"); var context = await server.SendAsync(c => { c.Request.Method = HttpMethods.Post; c.Request.Path = "/and/file.txt"; c.Request.QueryString = new QueryString("?and=query"); }); Assert.True(context.RequestAborted.CanBeCanceled); Assert.Equal(HttpProtocol.Http11, context.Request.Protocol); Assert.Equal("POST", context.Request.Method); Assert.Equal("https", context.Request.Scheme); Assert.Equal("example.com", context.Request.hst.Value); Assert.Equal("/A/Path", context.Request.PathBase.Value); Assert.Equal("/and/file.txt", context.Request.Path.Value); Assert.Equal("?and=query", context.Request.QueryString.Value); Assert.NotNull(context.Request.Body); Assert.NotNull(context.Request.Headers); Assert.NotNull(context.Response.Headers); Assert.NotNull(context.Response.Body); Assert.Equal(404, context.Response.StatusCode); Assert.Null(context.Features.Get().ReasonPhrase); } SendAsync allow the direct configuration of an HttpContext object instead of using the HttpClient abstractions. Use SendAsync to control structures only available on the server, like HttpContext.Items or HttpContext.Features. As with the Previous example that tested for a 404 - Not Found response, check the other for every assert statement within the preceding test. The check confirms that the test fails correctly when the middleware is working normally. After you've confirmed that the false-positive test works, set the ultimate assert statements for the expected conditions and values of the test. Run it again to verify that the test passes. Conclusion Using Middleware unit testing you can test parts of code which is placed in program. You can also get more detail result of your testing. Using these you can customize data structures, like HttpContext, directly within the test. You can test from both sides correct or wrong.We hope this blog will be helpful for you to understand concept of unit testing a custom middleware in ASP.NET Core.

Build Your Agile Team

Enter your e-mail address Please enter valid e-mail

Categories

Ensure your sustainable growth with our team

Talk to our experts
Sustainable
Sustainable
 

Blog Our insights

Next-Gen Programming Languages: Shaping the Future of Software Development in 2024
Next-Gen Programming Languages: Shaping the Future of Software Development in 2024

Introduction Imagine standing in line at the grocery store, waiting to pay for groceries. You pull out your phone and scan each item’s barcode with a single tap. This seemingly...

MySQL vs Azure SQL Database: Understanding Needs, Factors, and Performance Metrics
MySQL vs Azure SQL Database: Understanding Needs, Factors, and Performance Metrics

The world of technology is constantly changing, and databases are at the forefront of this evolution. We have explored different types of databases, both physical and cloud-based, and realized how each of them provides unique features to improve data accessibility and inclusive performance. Leading the pack are MySQL and Azure SQL database services , helping business elevate their processes to new heights.

Streamlining E-commerce Operations with Microsoft PowerApps
Streamlining E-commerce Operations with Microsoft PowerApps

In today's rapidly changing digital world, eCommerce is a dynamic industry. Every day, millions of transactions take place online, so companies are always looking for new and creative methods to improve consumer satisfaction and optimize operations.