{"id":48903,"date":"2019-09-30T08:00:15","date_gmt":"2019-09-30T06:00:15","guid":{"rendered":"https:\/\/code-maze.com\/?p=48903"},"modified":"2024-11-15T09:43:44","modified_gmt":"2024-11-15T08:43:44","slug":"aspnet-core-integration-testing","status":"publish","type":"post","link":"https:\/\/code-maze.com\/aspnet-core-integration-testing\/","title":{"rendered":"Integration Testing in ASP.NET Core"},"content":{"rendered":"<p>In this article, we will learn about Integration Testing in ASP.NET Core. Additionally, we will prepare an in-memory database so we don\u2019t have to use the real SQL server during integration tests. For that purpose, we will use the WebApplicationFactory class.<\/p>\n<div style=\"padding: 20px; border-left: 5px #dc2323 solid; display: block; margin-bottom: 20px; box-shadow: 1px 1px 5px 0px lightgrey;\">To download the source code for this article, you can visit <a href=\"https:\/\/github.com\/CodeMazeBlog\/testing-aspnetcore-mvc\/tree\/integration-testing-mvc\" target=\"_blank\" rel=\"nofollow noopener\">our GitHub repository<\/a>.<\/div>\n<p>To navigate this series, you can visit <a href=\"https:\/\/code-maze.com\/asp-net-core-testing\/\" target=\"_blank\" rel=\"noopener noreferrer\">ASP.NET Core Testing<\/a>.<\/p>\n<p>Let\u2019s move on.<\/p>\n<h2 id=\"introduction\">What is Integration Testing?<\/h2>\n<p><strong>Integration testing ensures that different components inside the application function correctly when working together.<\/strong> The main difference between integration testing and unit testing is that integration testing often includes an application&#8217;s infrastructure components like a database, file system, etc. When we work with unit tests, we mock these components. But with integration testing, we want to ensure that the whole app is working as expected with all of these components combined.<\/p>\n<h2 id=\"preparingnewproject\"><span lang=\"SR-LATN-RS\">Preparing a new Project for Integration Testing<\/span><\/h2>\n<p>So, let&#8217;s see how we can write integration tests in ASP.NET Core.<\/p>\n<p>First, we are going to create a new <code>xUnit<\/code> project named <code>EmployeesApp.IntegrationTests<\/code> for integration testing purposes.<\/p>\n<p>After the project creation, we are going to rename the <code>UnitTest1.cs<\/code> class to <code>EmployeesControllerIntegrationTests<\/code>.<\/p>\n<p>Additionally, <strong>we are going to reference the main project<\/strong> and install two NuGet packages required for testing purposes:<\/p>\n<ul>\n<li>AspNetCore.Mvc.Testing \u2013 this package provides the TestServer and an important class <code>WebApplicationFactory<\/code> to help us bootstrap our app in-memory<\/li>\n<li>Microsoft.EntityFrameworkCore.InMemory &#8211; In-memory database provider<\/li>\n<\/ul>\n<p>Now we can continue on.<\/p>\n<h2 id=\"inmemoryfactory\"><span lang=\"SR-LATN-RS\">Using WebApplicationFactory class for Creating In-Memory Factory Configuration<\/span><\/h2>\n<p>The <code>WebApplicationFactory<\/code> class is a factory that we can use to bootstrap an application in memory for functional end-to-end tests. With .NET 6, new templates were introduced without the <code>Startup<\/code> class. This affects the implementation of <code>WebApplicationFactory<\/code> class compared to what we used to in .NET 5.\u00a0\u00a0<\/p>\n<p>So, let&#8217;s see how we can use the WebApplicationFactory class in .NET 6 to create an in-memory factory configuration.\u00a0<\/p>\n<p>The first thing we are going to do is to create a new class <code>TestingWebAppFactory<\/code> and modify it:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class TestingWebAppFactory&lt;TEntryPoint&gt; : WebApplicationFactory&lt;Program&gt; where TEntryPoint : Program\r\n{\r\n    protected override void ConfigureWebHost(IWebHostBuilder builder)\r\n    {\r\n            \r\n    }\r\n}<\/pre>\n<p>For this to work, we need two namespaces included:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">using Microsoft.AspNetCore.Hosting;\r\nusing Microsoft.AspNetCore.Mvc.Testing;<\/pre>\n<p>Our class implements the <code>WebApplicationFactory&lt;Startup&gt;<\/code> class and overrides the <code>ConfigureWebHost<\/code> method, which allows us to configure the application before it gets built.<\/p>\n<p>But we have a small problem. Our class doesn&#8217;t recognize the <code>Program<\/code> class even though we have the reference from the main project. That&#8217;s because in .NET 6 compiler generates the <code>Program<\/code> class behind the scenes as the internal class, thus making it inaccessible in our integration testing project. <strong>So to solve this, we can create a <code>public partial Program<\/code> class in the Program.cs file<\/strong> in the main project:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"3\">app.Run();\r\n\r\npublic partial class Program { }<\/pre>\n<p>After this modification, our issue will disappear in the <code>TestWebAppFactory<\/code> class.<\/p>\n<h3>Implementation of the ConfigureWebHost Method<\/h3>\n<p>After we&#8217;ve fixed our issue, we can implement the <code>ConfigureWebHost<\/code> method:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class TestingWebAppFactory&lt;TEntryPoint&gt; : WebApplicationFactory&lt;Program&gt; where TEntryPoint : Program\r\n{\r\n    protected override void ConfigureWebHost(IWebHostBuilder builder)\r\n    {\r\n        builder.ConfigureServices(services =&gt;\r\n        {\r\n            var descriptor = services.SingleOrDefault(\r\n                d =&gt; d.ServiceType ==\r\n                    typeof(DbContextOptions&lt;EmployeeContext&gt;));\r\n\r\n            if (descriptor != null)\r\n                services.Remove(descriptor);\r\n\r\n            services.AddDbContext&lt;EmployeeContext&gt;(options =&gt;\r\n            {\r\n                options.UseInMemoryDatabase(\"InMemoryEmployeeTest\");\r\n            });\r\n\r\n            var sp = services.BuildServiceProvider();\r\n            using (var scope = sp.CreateScope())\r\n            using (var appContext = scope.ServiceProvider.GetRequiredService&lt;EmployeeContext&gt;())\r\n            {\r\n                try\r\n                {\r\n                    appContext.Database.EnsureCreated();\r\n                }\r\n                catch (Exception ex)\r\n                {\r\n                    \/\/Log errors or do anything you think it's needed\r\n                    throw;\r\n                }\r\n            }\r\n        });\r\n    }\r\n}<\/pre>\n<p>A couple of things to mention here.<\/p>\n<p>In the <code>ConfigureWebHost<\/code> method, we remove the EmployeeContext registration from the <code>Program<\/code> class.<\/p>\n<p>After that, we add the database context to the service container and instruct it to use the in-memory database instead of the real database.<\/p>\n<p>Finally, we ensure that we seed the data from the <code>EmployeeContext<\/code> class (The same data you inserted into a real SQL Server database at the beginning of this series).<\/p>\n<p>With these preparations in place, we can return to the test class and start writing our tests.<\/p>\n<h2 id=\"testingindexaction\"><span lang=\"SR-LATN-RS\">Integration Testing of the Index Action<\/span><\/h2>\n<p>In our test class, we can find a single test method with the default name. But let\u2019s remove it and start from scratch.<\/p>\n<p>The first thing we have to do is to implement a previously created <code>TestingWebAppFactory<\/code> class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class EmployeesControllerIntegrationTests : IClassFixture&lt;TestingWebAppFactory&lt;Program&gt;&gt;\r\n{\r\n    private readonly HttpClient _client;\r\n\r\n    public EmployeesControllerIntegrationTests(TestingWebAppFactory&lt;Program&gt; factory) \r\n        =&gt; _client = factory.CreateClient();\r\n}<\/pre>\n<p>So, we implement the <code>TestingWebAppFactory<\/code> class with the <code>IClassFixture<\/code> interface and inject it in a constructor, where we create an instance of the <code>HttpClient<\/code>. The <code>IClassFixture<\/code> interface is a decorator, which indicates that tests in this class rely on a fixture to run. We can see that the fixture is our <code>TestingWebAppFactory<\/code> class.<\/p>\n<p>Now, let&#8217;s write our first integration test:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[Fact]\r\npublic async Task Index_WhenCalled_ReturnsApplicationForm()\r\n{\r\n    var response = await _client.GetAsync(\"\/Employees\");\r\n\r\n    response.EnsureSuccessStatusCode();\r\n\r\n    var responseString = await response.Content.ReadAsStringAsync();\r\n\r\n    Assert.Contains(\"Mark\", responseString);\r\n    Assert.Contains(\"Evelin\", responseString);\r\n}<\/pre>\n<p>We use the <code>GetAsync<\/code> method to call the action on the <code>\/Employees<\/code> route, which is the <code>Index<\/code> action, and return a result in a <code>response<\/code> variable. With the <code>EnsureSuccessStatusCode<\/code> method, we verify that the <code>IsSuccessStatusCode<\/code> property is set to true.<\/p>\n<p>If it is false, it means that the request is not successful, and the test will fail.<\/p>\n<div style=\"padding: 20px; border-left: 5px gray solid; display: block; margin-bottom: 20px; box-shadow: 1px 1px 5px 0px lightgrey;\">To learn more about the HttpClient class and request and response actions, you can read <a href=\"https:\/\/code-maze.com\/httpclient-with-asp-net-core-tutorial\/\" target=\"_blank\" rel=\"noopener\">our tutorial about HttpClient in ASP.NET Core<\/a>.<\/div>\n<p>Finally, we serialize our HTTP content to a string using the <code>ReadAsStringAsync<\/code> method and verify that it contains our two employees.<\/p>\n<p>Right now, if we start the test runner, our test will fail due to the migration issue:<\/p>\n<p><code>System.InvalidOperationException : Relational-specific methods can only be used when the context is using a relational database provider.<\/code><\/p>\n<p>That&#8217;s because our <code>MigrationManager<\/code> class can execute migrations only with the real SQL server and not with the in-memory one. So to fix this issue, we are going to modify the try block in that class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"3-4\">try\r\n{\r\n    if (appContext.Database.ProviderName != \"Microsoft.EntityFrameworkCore.InMemory\")\r\n        appContext.Database.Migrate();\r\n}<\/pre>\n<p>Now, we can run our test:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/11\/10-Integration-tests-of-the-Index-action-in-ASP.NET-Core.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-60237 size-full\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/11\/10-Integration-tests-of-the-Index-action-in-ASP.NET-Core.png\" alt=\"Integration testing of the Index action in ASP.NET Core\" width=\"378\" height=\"191\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/11\/10-Integration-tests-of-the-Index-action-in-ASP.NET-Core.png 378w, https:\/\/code-maze.com\/wp-content\/uploads\/2021\/11\/10-Integration-tests-of-the-Index-action-in-ASP.NET-Core-300x152.png 300w\" sizes=\"auto, (max-width: 378px) 100vw, 378px\" \/><\/a><\/p>\n<p>We can see that the test passed and that we successfully returned our employees from the in-memory database. If you want to ensure that we are really using the in-memory database and not the real one, you can always stop the SQLServer service in the Services window and run the test again.<\/p>\n<p>Excellent!<\/p>\n<p>Now, we can continue towards the integration testing of both <code>Create<\/code> actions.<\/p>\n<h2 id=\"testingcreateaction\"><span lang=\"SR-LATN-RS\">Integration Testing of the Create (GET) Action in ASP.NET Core<\/span><\/h2>\n<p>Before we continue with testing, let\u2019s open the <code>Create.cshtml<\/code> file, from the <code>Views\\Employees<\/code> folder, and modify it by changing the <code>h4<\/code> tag (just to have more than one word to test):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">&lt;h4&gt;Please provide a new employee data&lt;\/h4&gt;<\/pre>\n<p>Great.<\/p>\n<p>Now, we are ready to write our test code.<\/p>\n<p>We want to verify when the Create (GET) action executes, it returns a create form:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[Fact]\r\npublic async Task Create_WhenCalled_ReturnsCreateForm()\r\n{\r\n    var response = await _client.GetAsync(\"\/Employees\/Create\");\r\n\r\n    response.EnsureSuccessStatusCode();\r\n\r\n    var responseString = await response.Content.ReadAsStringAsync();\r\n\r\n    Assert.Contains(\"Please provide a new employee data\", responseString);\r\n}<\/pre>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/11\/11-Integration-testing-of-the-Create-GET-Action-to-return-a-create-form.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-60239\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/11\/11-Integration-testing-of-the-Create-GET-Action-to-return-a-create-form.png\" alt=\"Integration testing of the Create GET Action to return a create form\" width=\"379\" height=\"150\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/11\/11-Integration-testing-of-the-Create-GET-Action-to-return-a-create-form.png 379w, https:\/\/code-maze.com\/wp-content\/uploads\/2021\/11\/11-Integration-testing-of-the-Create-GET-Action-to-return-a-create-form-300x119.png 300w\" sizes=\"auto, (max-width: 379px) 100vw, 379px\" \/><\/a><\/p>\n<p>And it does.<\/p>\n<h2 id=\"additionaltests\"><span lang=\"SR-LATN-RS\">Testing the Create (POST) Action<\/span><\/h2>\n<p>To continue, we will write some integration testing code for the POST action. For the first test method, we will verify that our action returns a view with an appropriate error message when the model sent from the <code>Create<\/code> page, is invalid. And yes, in a <a href=\"https:\/\/code-maze.com\/unit-testing-controllers-aspnetcore-moq\" target=\"_blank\" rel=\"noopener noreferrer\">previous article<\/a>, we had test methods for the invalid model, but without an HTTP request.<\/p>\n<p>That said, let\u2019s write the test code:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[Fact]\r\npublic async Task Create_SentWrongModel_ReturnsViewWithErrorMessages()\r\n{\r\n    var postRequest = new HttpRequestMessage(HttpMethod.Post, \"\/Employees\/Create\");\r\n\r\n    var formModel = new Dictionary&lt;string, string&gt;\r\n    {\r\n        { \"Name\", \"New Employee\" },\r\n        { \"Age\", \"25\" }\r\n    };\r\n\r\n    postRequest.Content = new FormUrlEncodedContent(formModel);\r\n            \r\n    var response = await _client.SendAsync(postRequest);\r\n            \r\n    response.EnsureSuccessStatusCode();\r\n            \r\n    var responseString = await response.Content.ReadAsStringAsync();\r\n            \r\n    Assert.Contains(\"Account number is required\", responseString);\r\n}<\/pre>\n<p>We create a post request and the <code>formModel<\/code> object as a dictionary, which consists of the elements that we have on the Create page. Of course, we didn\u2019t provide all the elements, the <code>AccountNumber<\/code> is missing because we want to send invalid data.<\/p>\n<p>After that, we store the <code>formModel<\/code> as a content in our request, send that request with the <code>SendAsync<\/code> method and ensure that the response is successful.<\/p>\n<p>Finally, we serialize our response and verify assertions.<\/p>\n<p>If we take a look at the <code>Employee<\/code> model class, we are going to see that if the <code>AccountNumber<\/code> is not provided, the error message should appear on the form:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[Required(ErrorMessage = \"Account number is required\")] \r\npublic string AccountNumber { get; set; }<\/pre>\n<p>That is exactly what we verify in our test method.<\/p>\n<p>Now, we can run the Test Explorer:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/11\/12-Integration-testing-of-the-Create-POST-Action-that-fails.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-60243\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/11\/12-Integration-testing-of-the-Create-POST-Action-that-fails.png\" alt=\"Integration testing of the Create POST Action that fails\" width=\"486\" height=\"236\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/11\/12-Integration-testing-of-the-Create-POST-Action-that-fails.png 486w, https:\/\/code-maze.com\/wp-content\/uploads\/2021\/11\/12-Integration-testing-of-the-Create-POST-Action-that-fails-300x146.png 300w\" sizes=\"auto, (max-width: 486px) 100vw, 486px\" \/><\/a><\/p>\n<p>Well, this test fails. But there is nothing wrong with the code; the test code is good. For some reason, we are getting the 400 Bad Request message.<\/p>\n<p>Why is that?<\/p>\n<h3>The ValidateAntiForgeryToken Attribute Causing Integration Test to Fail<\/h3>\n<p>If we open our controller and\u00a0<span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">look at the Create (POST) action, we can see the\u00a0<a href=\"https:\/\/code-maze.com\/aspnet-core-testing-anti-forgery-token\" target=\"_blank\" rel=\"noopener\">ValidateAntiForgeryToken<\/a> attribute. Our action expects the anti-forgery token to be provided, but we are not doing that, so the test fails. For now (just as a temporary solution),<\/span>\u00a0we are going to comment out that attribute and run the test again.<\/p>\n<p>Now, the test passes. As we said, this is just a temporary solution. There are a couple of steps required to configure the Anti-Forgery token in our testing code, and in the next article, we are going to show you how to do that step by step. For now, let&#8217;s just continue with another test while the <code>ValidateAntiForgeryToken<\/code> is commented out.<\/p>\n<h3><span lang=\"SR-LATN-RS\">Testing Successful POST Request<\/span><\/h3>\n<p>Let&#8217;s write the final test in this article, where we verify that the Create action returns the Index view if the POST request is successful:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">[Fact] \r\npublic async Task Create_WhenPOSTExecuted_ReturnsToIndexViewWithCreatedEmployee() \r\n{ \r\n    var postRequest = new HttpRequestMessage(HttpMethod.Post, \"\/Employees\/Create\"); \r\n            \r\n    var formModel = new Dictionary&lt;string, string&gt; \r\n    { \r\n        { \"Name\", \"New Employee\" }, \r\n        { \"Age\", \"25\" }, \r\n        { \"AccountNumber\", \"214-5874986532-21\" } \r\n    }; \r\n            \r\n    postRequest.Content = new FormUrlEncodedContent(formModel); \r\n            \r\n    var response = await _client.SendAsync(postRequest); \r\n            \r\n    response.EnsureSuccessStatusCode(); \r\n            \r\n    var responseString = await response.Content.ReadAsStringAsync(); \r\n            \r\n    Assert.Contains(\"New Employee\", responseString); \r\n    Assert.Contains(\"214-5874986532-21\", responseString); \r\n}<\/pre>\n<p>So, this code is not too much different from the previous one, except we send a valid <code>formModel<\/code> object with the request and the assertion part. Basically, once the POST request is finished successfully, the <code>Create<\/code> method should redirect us to the <code>Index<\/code> method. There, we can find all the employees, including the created one. You can always debug your test code and inspect the <code>responseString<\/code> variable to visually confirm that the response is the <code>Index<\/code> page with a new employee.<\/p>\n<p>Once we run the Test Explorer, the test will pass.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>In this article, we have learned about integration testing in ASP.NET Core. We have created an In-Memory database to use during tests instead of the real database server. Additionally, we have learned how to test our Index action and how to write integration tests for the Create actions. This testing methodology could also be applied to other actions (PUT, Delete&#8230;).<\/p>\n<p>Finally, we have seen the problem with the anti-forgery token<span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">.\u00a0<a href=\"https:\/\/code-maze.com\/aspnet-core-testing-anti-forgery-token\" target=\"_blank\" rel=\"noopener\">In the next article<\/a>, we will<\/span>\u00a0learn how to solve that problem by introducing several new functionalities to our code.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we will learn about Integration Testing in ASP.NET Core. Additionally, we will prepare an in-memory database so we don\u2019t have to use the real SQL server during integration tests. For that purpose, we will use the WebApplicationFactory class. To navigate this series, you can visit ASP.NET Core Testing. Let\u2019s move on. What [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":54878,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[12],"tags":[79,577,539],"class_list":["post-48903","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-csharp","tag-asp-net-core","tag-integration-testing","tag-mvc","et-has-post-format-content","et_post_format-et-post-format-standard"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Integration Testing in ASP.NET Core - Code Maze<\/title>\n<meta name=\"description\" content=\"We are going to learn about Integration testing in ASP.NET Core, and how to use WebApplicationFactory class that helps in the process.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/code-maze.com\/aspnet-core-integration-testing\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Integration Testing in ASP.NET Core - Code Maze\" \/>\n<meta property=\"og:description\" content=\"We are going to learn about Integration testing in ASP.NET Core, and how to use WebApplicationFactory class that helps in the process.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/code-maze.com\/aspnet-core-integration-testing\/\" \/>\n<meta property=\"og:site_name\" content=\"Code Maze\" \/>\n<meta property=\"article:published_time\" content=\"2019-09-30T06:00:15+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-11-15T08:43:44+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/code-maze.com\/wp-content\/uploads\/2019\/09\/03-integration-testing-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1100\" \/>\n\t<meta property=\"og:image:height\" content=\"620\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Marinko Spasojevi\u0107\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/CodeMazeBlog\" \/>\n<meta name=\"twitter:site\" content=\"@CodeMazeBlog\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Marinko Spasojevi\u0107\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/code-maze.com\/aspnet-core-integration-testing\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/aspnet-core-integration-testing\/\"},\"author\":{\"name\":\"Marinko Spasojevi\u0107\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/d6fa06e66820968d19b39fb63cff2533\"},\"headline\":\"Integration Testing in ASP.NET Core\",\"datePublished\":\"2019-09-30T06:00:15+00:00\",\"dateModified\":\"2024-11-15T08:43:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/code-maze.com\/aspnet-core-integration-testing\/\"},\"wordCount\":1495,\"commentCount\":23,\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/aspnet-core-integration-testing\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2019\/09\/03-integration-testing-1.png\",\"keywords\":[\"asp.net core\",\"Integration Testing\",\"MVC\"],\"articleSection\":[\"C#\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/code-maze.com\/aspnet-core-integration-testing\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/code-maze.com\/aspnet-core-integration-testing\/\",\"url\":\"https:\/\/code-maze.com\/aspnet-core-integration-testing\/\",\"name\":\"Integration Testing in ASP.NET Core - Code Maze\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/code-maze.com\/aspnet-core-integration-testing\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/aspnet-core-integration-testing\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2019\/09\/03-integration-testing-1.png\",\"datePublished\":\"2019-09-30T06:00:15+00:00\",\"dateModified\":\"2024-11-15T08:43:44+00:00\",\"description\":\"We are going to learn about Integration testing in ASP.NET Core, and how to use WebApplicationFactory class that helps in the process.\",\"breadcrumb\":{\"@id\":\"https:\/\/code-maze.com\/aspnet-core-integration-testing\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/code-maze.com\/aspnet-core-integration-testing\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/aspnet-core-integration-testing\/#primaryimage\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2019\/09\/03-integration-testing-1.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2019\/09\/03-integration-testing-1.png\",\"width\":1100,\"height\":620,\"caption\":\"03 integration testing\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/code-maze.com\/aspnet-core-integration-testing\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/code-maze.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Integration Testing in ASP.NET Core\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/code-maze.com\/#website\",\"url\":\"https:\/\/code-maze.com\/\",\"name\":\"Code Maze\",\"description\":\"Learn. Code. Succeed.\",\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/code-maze.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/code-maze.com\/#organization\",\"name\":\"Code Maze\",\"url\":\"https:\/\/code-maze.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"width\":3511,\"height\":3510,\"caption\":\"Code Maze\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/CodeMazeBlog\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/d6fa06e66820968d19b39fb63cff2533\",\"name\":\"Marinko Spasojevi\u0107\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/marinko-1x1-3-150x150.jpg\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/marinko-1x1-3-150x150.jpg\",\"caption\":\"Marinko Spasojevi\u0107\"},\"description\":\"Hi, my name is Marinko Spasojevic. Currently, I work as a full-time .NET developer and my passion is web application development. Just getting something to work is not enough for me. To make it just how I like it, it must be readable, reusable, and easy to maintain. Prior to being an author on the CodeMaze blog, I had been working as a professor of Computer Science for several years. So, sharing knowledge while working as a full-time developer comes naturally to me.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/marinko-spasojevic\/\",\"https:\/\/x.com\/https:\/\/twitter.com\/CodeMazeBlog\"],\"url\":\"https:\/\/code-maze.com\/author\/marinko\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Integration Testing in ASP.NET Core - Code Maze","description":"We are going to learn about Integration testing in ASP.NET Core, and how to use WebApplicationFactory class that helps in the process.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/code-maze.com\/aspnet-core-integration-testing\/","og_locale":"en_US","og_type":"article","og_title":"Integration Testing in ASP.NET Core - Code Maze","og_description":"We are going to learn about Integration testing in ASP.NET Core, and how to use WebApplicationFactory class that helps in the process.","og_url":"https:\/\/code-maze.com\/aspnet-core-integration-testing\/","og_site_name":"Code Maze","article_published_time":"2019-09-30T06:00:15+00:00","article_modified_time":"2024-11-15T08:43:44+00:00","og_image":[{"width":1100,"height":620,"url":"https:\/\/code-maze.com\/wp-content\/uploads\/2019\/09\/03-integration-testing-1.png","type":"image\/png"}],"author":"Marinko Spasojevi\u0107","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/CodeMazeBlog","twitter_site":"@CodeMazeBlog","twitter_misc":{"Written by":"Marinko Spasojevi\u0107","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/code-maze.com\/aspnet-core-integration-testing\/#article","isPartOf":{"@id":"https:\/\/code-maze.com\/aspnet-core-integration-testing\/"},"author":{"name":"Marinko Spasojevi\u0107","@id":"https:\/\/code-maze.com\/#\/schema\/person\/d6fa06e66820968d19b39fb63cff2533"},"headline":"Integration Testing in ASP.NET Core","datePublished":"2019-09-30T06:00:15+00:00","dateModified":"2024-11-15T08:43:44+00:00","mainEntityOfPage":{"@id":"https:\/\/code-maze.com\/aspnet-core-integration-testing\/"},"wordCount":1495,"commentCount":23,"publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"image":{"@id":"https:\/\/code-maze.com\/aspnet-core-integration-testing\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2019\/09\/03-integration-testing-1.png","keywords":["asp.net core","Integration Testing","MVC"],"articleSection":["C#"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/code-maze.com\/aspnet-core-integration-testing\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/code-maze.com\/aspnet-core-integration-testing\/","url":"https:\/\/code-maze.com\/aspnet-core-integration-testing\/","name":"Integration Testing in ASP.NET Core - Code Maze","isPartOf":{"@id":"https:\/\/code-maze.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/code-maze.com\/aspnet-core-integration-testing\/#primaryimage"},"image":{"@id":"https:\/\/code-maze.com\/aspnet-core-integration-testing\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2019\/09\/03-integration-testing-1.png","datePublished":"2019-09-30T06:00:15+00:00","dateModified":"2024-11-15T08:43:44+00:00","description":"We are going to learn about Integration testing in ASP.NET Core, and how to use WebApplicationFactory class that helps in the process.","breadcrumb":{"@id":"https:\/\/code-maze.com\/aspnet-core-integration-testing\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/code-maze.com\/aspnet-core-integration-testing\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/aspnet-core-integration-testing\/#primaryimage","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2019\/09\/03-integration-testing-1.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2019\/09\/03-integration-testing-1.png","width":1100,"height":620,"caption":"03 integration testing"},{"@type":"BreadcrumbList","@id":"https:\/\/code-maze.com\/aspnet-core-integration-testing\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/code-maze.com\/"},{"@type":"ListItem","position":2,"name":"Integration Testing in ASP.NET Core"}]},{"@type":"WebSite","@id":"https:\/\/code-maze.com\/#website","url":"https:\/\/code-maze.com\/","name":"Code Maze","description":"Learn. Code. Succeed.","publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/code-maze.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/code-maze.com\/#organization","name":"Code Maze","url":"https:\/\/code-maze.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","width":3511,"height":3510,"caption":"Code Maze"},"image":{"@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/CodeMazeBlog"]},{"@type":"Person","@id":"https:\/\/code-maze.com\/#\/schema\/person\/d6fa06e66820968d19b39fb63cff2533","name":"Marinko Spasojevi\u0107","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/person\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/marinko-1x1-3-150x150.jpg","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/marinko-1x1-3-150x150.jpg","caption":"Marinko Spasojevi\u0107"},"description":"Hi, my name is Marinko Spasojevic. Currently, I work as a full-time .NET developer and my passion is web application development. Just getting something to work is not enough for me. To make it just how I like it, it must be readable, reusable, and easy to maintain. Prior to being an author on the CodeMaze blog, I had been working as a professor of Computer Science for several years. So, sharing knowledge while working as a full-time developer comes naturally to me.","sameAs":["https:\/\/www.linkedin.com\/in\/marinko-spasojevic\/","https:\/\/x.com\/https:\/\/twitter.com\/CodeMazeBlog"],"url":"https:\/\/code-maze.com\/author\/marinko\/"}]}},"_links":{"self":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/48903","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/comments?post=48903"}],"version-history":[{"count":8,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/48903\/revisions"}],"predecessor-version":[{"id":123689,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/48903\/revisions\/123689"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media\/54878"}],"wp:attachment":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media?parent=48903"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/categories?post=48903"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/tags?post=48903"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}