Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ivaylokenov/MyTested.AspNetCore.Mvc

Fluent testing library for ASP.NET Core MVC.
https://github.com/ivaylokenov/MyTested.AspNetCore.Mvc

asp-net-core asp-net-core-mvc assertion-library assertion-methods fluent-testing mvc test-framework

Last synced: about 2 months ago
JSON representation

Fluent testing library for ASP.NET Core MVC.

Awesome Lists containing this project

README

        


MyTested.AspNetCore.Mvc  MyTested.AspNetCore.Mvc - Fluent Testing
  Library for ASP.NET Core MVC

## Diamond Sponsors









## Gold Sponsors














## Special Sponsors





The Ultimate Cross-Platform .NET Framework




JetBrains



## Project Description

**MyTested.AspNetCore.Mvc** is a strongly-typed unit testing library providing an easy fluent interface to test the [ASP.NET Core](https://github.com/aspnet/AspNetCore) framework, perfectly suitable for both MVC and API scenarios. It is testing framework agnostic so that you can combine it with a test runner of your choice (e.g. [xUnit](https://github.com/xunit/xunit), [NUnit](https://github.com/nunit/nunit), etc.).

*Windows:* [![Build status](https://ci.appveyor.com/api/projects/status/3xlag3a7f87bg4on?svg=true)](https://ci.appveyor.com/project/ivaylokenov/mytested-aspnetcore-mvc)

*Ubuntu & Mac OS:* [![Build Status](https://travis-ci.org/ivaylokenov/MyTested.AspNetCore.Mvc.svg?branch=development)](https://travis-ci.com/ivaylokenov/MyTested.AspNetCore.Mvc)

*Downloads:* [![NuGet Badge](https://buildstats.info/nuget/MyTested.AspNetCore.Mvc)](https://www.nuget.org/packages/MyTested.AspNetCore.Mvc/)

**MyTested.AspNetCore.Mvc** has [more than 500 assertion methods](https://MyTestedASP.NET/Core/Mvc/Features) and is 100% covered by [more than 2500 unit tests](https://github.com/ivaylokenov/MyTested.AspNetCore.Mvc/tree/version-3.1/test). It should work correctly. Almost all items in the [issues page](https://github.com/ivaylokenov/MyTested.AspNetCore.Mvc/issues) are expected future features and enhancements.

**MyTested.AspNetCore.Mvc** helps you speed up the testing process in your web development team! If you find that statement unbelievable, these are the words which some of the many happy **MyTested.AspNetCore.Mvc** users once said:
> "I’ve been using your packages for almost 3 years now and it has saved me countless hours in creating unit tests and wanted to thank you for making this. I cannot imagine how much code I would have had to write to create the 450+ and counting unit tests I have for my controllers."

> "I absolutely love this library and it greatly improved the unit/integration test experience in my team."

> ["Amazing library, makes you want to do test-driven development, thanks!"](https://github.com/ivaylokenov/MyTested.AspNetCore.Mvc/issues/265#issue-194578165)

> "Wanted to thank you for your effort and time required to create this. This is a great tool! Keep up the good work."

Take a look around and...

⭐️ ...if you like the library, **star** the repository and **show** it to your friends!

😏 ...if you find it useful, make sure you **subscribe** for future releases by clicking the **"Watch"** button and choosing **"Releases only"**!

👀 ...if you want to learn cool C# coding techniques, **subscribe** to my **[YouTube channel](https://www.youtube.com/channel/UCP5Ons7fK3yKhX6lhc9XcfQ)**, where I regularly post online video lessons!

✔ ...if you want to **support** the project, **[become a sponsor/backer](#sponsors--backers)**!

#### Featured in

- [The official ASP.NET Core MVC documentation](https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/testing?view=aspnetcore-3.0#additional-resources)
- [The official ASP.NET Core MVC repository](https://github.com/aspnet/AspNetCore/tree/master/src/Mvc#aspnet-core-mvc)
- [NuGet Package of the week in "The week in .NET – 6/28/2016"](https://devblogs.microsoft.com/dotnet/the-week-in-net-6282016/)
- [Awesome .NET Core](https://github.com/thangchung/awesome-dotnet-core#testing)

## Sponsors & Backers

**MyTested.AspNetCore.Mvc** is a community-driven open source library. It's an independent project with its ongoing development made possible thanks to the support by all my awesome backers. If you'd like to join them, please consider:

- [Become a backer or sponsor on Patreon](https://www.patreon.com/ivaylokenov)
- [Become a backer or sponsor on OpenCollective](https://opencollective.com/mytestedaspnet)
- [One-time donation via PayPal](http://paypal.me/ivaylokenov)
- [One-time donation via Buy Me A Coffee](http://buymeacoff.ee/ivaylokenov)
- One-time donation via cryptocurrencies:
- BTC (Bitcoin) - 3P49XMiGXxqR2Dq1HdqHpkCa6UD848rpBU
- BCH (Bitcoin Cash) - qqgyjlvmuydf6gtfhfdypyw2u8utmc3uqg4nwma3y4
- ETH (Ethereum) - 0x2bc55e4b1B9b296B751738631CD24b2f701E588F
- LTC (Litecoin) - MQ1GJum1QuqAuUsc6LarE3Z6TQQJ3rJwsA

#### What's the difference between Patreon and OpenCollective?

Funds donated via both platforms are used for development and marketing purposes. Funds donated via [OpenCollective](https://opencollective.com/mytestedaspnet) are managed with transparent expenses. Your name/logo will receive proper recognition and exposure by donating on either platform.

Additionally, funds donated via [Patreon](https://www.patreon.com/ivaylokenov) give me the freedom to continue the library development.

## Main Features

- **Built-in service mock resolver** - register your mocks once, use them everywhere.
- **Full request setup** - excellent arrangement of fake request data.
- **Detailed response assertions** - precise validation for all available result objects.
- **Controller tests** - unit or integration tests for both MVC and API scenarios.
- **View component tests** - validate your view logic as fast as possible.
- **Route tests** - asserting route paths and model binding is as accessible as it can get.
- **Pipeline tests** - from the web request to the returned response - the whole chain is validated.
- **Simple and easy to learn fluent API** - takes no more than 20 minutes to learn the library.
- **Strongly-typed assertions** - the fluent test chain is designed to be developer-friendly and helpful.
- **Friendly error messages** - failed tests throw exceptions with detailed error reports.
- **Isolated test scope** - each test is run in isolated scope, making asynchronous execution more than welcome.
- **Built-in mocks** - in-memory database, authentication, authorization, session, caching, temp data, and more.

## Quick Start

This quick start is for ASP.NET Core 3.1. For previous versions, check the [corresponding branches](https://github.com/ivaylokenov/MyTested.AspNetCore.Mvc/branches).

To add **MyTested.AspNetCore.Mvc** to your solution, you must follow these simple steps:

1. Create a test project.
2. Reference your web application.
3. Install **`MyTested.AspNetCore.Mvc.Universe`** (or just the [testing packages](#package-installation) you need) from [NuGet](https://www.nuget.org/packages/MyTested.AspNetCore.Mvc.Universe/).
4. Create a `testsettings.json` file at the root of the test project, set its `Copy to Output Directory` property to `Copy if newer`, and set your required application settings to fake ones:

```json
{
"ConnectionStrings": {
"DefaultConnection": "My Fake Connection String"
},
"AllowedHosts": "*"
}
```

5. Your test project's `.csproj` file should be similar to this one:

```xml


netcoreapp3.1



PreserveNewest










```

6. Create a `TestStartup` class at the root of the test project to register the dependency injection services, which will be used by all test cases in the assembly. A quick solution is to inherit from the web project's `Startup` class. By default **MyTested.AspNetCore.Mvc** replaces all ASP.NET Core services with ready to be used mocks. You only need to replace your own custom services with mocked ones by using the provided extension methods.

```c#
namespace MyApp.Tests
{
using MyTested.AspNetCore.Mvc;

using Microsoft.Extensions.DependencyInjection;

public class TestStartup : Startup
{
public void ConfigureTestServices(IServiceCollection services)
{
base.ConfigureServices(services);

// Replace only your own custom services. The ASP.NET Core ones
// are already replaced by MyTested.AspNetCore.Mvc.
services.Replace();
}
}
}
```

7. Create a test case by using the fluent API the library provides. You are given a static `MyMvc` class from which all assertions can be easily configured:

```c#
namespace MyApp.Tests.Controllers
{
using MyTested.AspNetCore.Mvc;

using MyApp.Controllers;
using Xunit;

public class HomeControllerShould
{
[Fact]
public void ReturnOkWithCorrectModelWhenCallingAuthenticatedIndexAction()
=> MyMvc // Start a test case.
.Controller(instance => instance // Arrange the controller under test.
.WithUser("TestUser") // Set an authenticated user to the request.
.WithData(MyTestData.GetData())) // Populate the application DbContext.
.Calling(c => c.Index()) // Act - invoke the action under test.
.ShouldReturn() // Assert action behavior.
.Ok(result => result // Validate the action result type.
.WithModelOfType>() // Check the response model type.
.Passing(model => model.Count == 10)); // Assert specific model properties.
}
}
```

Basically, **MyTested.AspNetCore.Mvc** throws an unhandled exception with a friendly error message if the assertion does not pass and the test fails. The example uses [xUnit](http://xunit.github.io/), but you can use any other framework you like. See the [samples](https://github.com/ivaylokenov/MyTested.AspNetCore.Mvc/tree/version-3.1/samples) for other types of test runners and `Startup` class configurations.

## Detailed Documentation

It is **strongly advised** to read the [tutorial](https://docs.mytestedasp.net/tutorial/intro.html) or watch [this online video lesson](https://www.youtube.com/watch?v=Tf2P-410Za4) to get familiar with **MyTested.AspNetCore.Mvc** in more details. Additionally, you may see the [testing guide](https://docs.mytestedasp.net/guide/intro.html) or the [API reference](https://docs.mytestedasp.net/api/index.html) for a full list of available features.

You can also check out the [provided samples](https://github.com/ivaylokenov/MyTested.AspNetCore.Mvc/tree/version-3.1/samples) for real-life ASP.NET Core MVC application testing.

## Test Examples

Here are some examples of how **powerful** the fluent testing API actually is!

**MyTested.AspNetCore.Mvc** is so **awesome** that each test can be written in **one single line** like in this [application sample](https://github.com/ivaylokenov/MyTested.AspNetCore.Mvc/tree/version-3.1/samples/Blog)!

### Controller Integration Tests

A controller integration test uses the globally registered services from the `TestStartup` class:

```c#
// Instantiates controller with the registered global services,
// and mocks authenticated user,
// and tests for valid model state,
// and tests for added by the action view bag entry,
// and tests for view result and model with specific assertions.
MyController
.Instance(instance => instance
.WithUser(user => user
.WithUsername("MyUserName")))
.Calling(c => c.MyAction(myRequestModel))
.ShouldHave()
.ValidModelState()
.AndAlso()
.ShouldHave()
.ViewBag(viewBag => viewBag
.ContainingEntry("MyViewBagProperty", "MyViewBagValue"))
.AndAlso()
.ShouldReturn()
.View(result => result
.WithModelOfType()
.Passing(model =>
{
Assert.AreEqual(1, model.Id);
Assert.AreEqual("My property value", model.MyProperty);
}));

// Instantiates controller with the registered global services,
// and sets options for the current test,
// and sets session for the current test,
// and sets DbContext data for the current test,
// and tests for added by the action cache entry,
// and tests for view result with specific model type.
MyController
.Instance(instance => instance
.WithOptions(options => options
.For(settings => settings.Cache = true))
.WithSession(session => session
.WithEntry("MySession", "MySessionValue"))
.WithData(data => data
.WithEntities(entities => entities
.AddRange(MyDataProvider.GetMyModels()))))
.Calling(c => c.MyAction())
.ShouldHave()
.MemoryCache(cache => cache
.ContainingEntry(entry => entry
.WithKey("MyCacheEntry")
.WithSlidingExpiration(TimeSpan.FromMinutes(10))
.WithValueOfType()
.Passing(cacheModel => cacheModel.Id == 1)))
.AndAlso()
.ShouldReturn()
.Ok(result => result
.WithModelOfType());

// Instantiates controller with the registered global services,
// and tests for valid model state,
// and tests for saved data in the DbContext after the action call,
// and tests for added by the action temp data entry with а specific key,
// and tests for redirect result to a specific action.
MyController
.Calling(c => c.MyAction(new MyFormModel
{
Title = title,
Content = content
}))
.ShouldHave()
.ValidModelState()
.AndAlso()
.ShouldHave()
.Data(data => data
.WithSet(set => set
.Should() // Uses FluentAssertions.
.NotBeEmpty()
.And
.ContainSingle(model => model.Title == title)))
.AndAlso()
.ShouldHave()
.TempData(tempData => tempData
.ContainingEntryWithKey(ControllerConstants.SuccessMessage))
.AndAlso()
.ShouldReturn()
.Redirect(result => result
.To(c => c.AnotherAction()));
```

The last test uses [Fluent Assertions](https://github.com/fluentassertions/fluentassertions) to further enhance the testing API. Another good alternative is [Shouldly](https://github.com/shouldly/shouldly).

### Controller Unit Tests

A controller unit test uses service mocks explicitly provided in each separate assertion:

```c#
// Instantiates controller with the provided service mocks,
// and tests for view result.
MyController
.Instance(instance => instance
.WithDependencies(
serviceMock,
anotherServiceMock,
From.Services())) // Provides a global service.
.Calling(c => c.MyAction())
.ShouldReturn()
.Accepted();

// Instantiates controller with the provided service mocks,
// and tests for view result.
MyController
.Instance(instance => instance
.WithDependencies(dependencies => dependencies
.With(serviceMock)
.WithNo())) // Provides null for IAnotherService.
.Calling(c => c.MyAction(From.Services())) // Provides a global service.
.ShouldReturn()
.View();
```

### Route Tests

A route test validates the web application's routing configuration, without executing the defined filters:

```c#
// Tests a route for correct controller, action, and resolved route values.
MyRouting
.Configuration()
.ShouldMap("/My/Action/1")
.To(c => c.Action(1));

// Tests a route for correct controller, action, and resolved route values
// with post request and submitted form.
MyRouting
.Configuration()
.ShouldMap(request => request
.WithMethod(HttpMethod.Post)
.WithLocation("/My/Action")
.WithFormFields(new
{
Title = title,
Content = content
}))
.To(c => c.Action(new MyFormModel
{
Title = title,
Content = content
}))
.AndAlso()
.ToValidModelState();

// Tests a route for correct controller, action, and resolved route values
// with post request and JSON body.
MyRouting
.Configuration()
.ShouldMap(request => request
.WithLocation("/My/Action/1")
.WithMethod(HttpMethod.Post)
.WithJsonBody(new
{
Integer = 1,
String = "Text"
}))
.To(c => c.Action(1, new MyJsonModel
{
Integer = 1,
String = "Text"
}))
.AndAlso()
.ToValidModelState();
```

*Note: route tests do not execute action filters.*

### Pipeline tests

A pipeline test provides strongly-typed assertions for the MVC pipeline (from routing to action result, including the application filters):

```c#
// Tests a route for correct route values,
// and validates whether the controller action
// with an authenticated user and the provided data
// returns redirect result to a specific action,
// while resolving services from the `TestStartup` class.
MyMvc
.Pipeline()
.ShouldMap(request => request
.WithLocation("/My/Action/1")
.WithMethod(HttpMethod.Post)
.WithUser()
.WithAntiForgeryToken()
.WithJsonBody(new
{
Integer = 1,
String = "Text"
}))
.To(c => c.Action(1))
.Which(controller => controller
.WithData(MyDataProvider.GetMyModels()))
.ShouldReturn()
.Redirect(redirect => redirect
.To(c => c.AnotherAction()));

// Tests a route for correct route values,
// and validates whether the controller action
// with the provided data
// returns view result with a specific model,
// while resolving services from the provided mocks.
MyMvc
.Pipeline()
.ShouldMap("/My/Action/1")
.To(c => c.Action(1))
.Which(controller => controller
.WithData(MyDataProvider.GetMyModels())
.WithDependencies(
serviceMock,
anotherServiceMock))
.ShouldReturn()
.View(result => result
.WithModelOfType());
```

*Note: pipeline tests execute action filters.*

*Note: pipeline tests does not run the server middleware configuration.*

*Note: pipeline tests are available from version 3.0.0 onwards.*

### Attribute Declaration Tests

An attribute declaration test validates controller and action attribute declarations:

```c#
// Tests for specific controller attributes - Area and Authorize.
MyController
.ShouldHave()
.Attributes(attributes => attributes
.SpecifyingArea(ControllerConstants.AdministratorArea)
.RestrictingForAuthorizedRequests(ControllerConstants.AdministratorRole));

// Tests for specific action attributes - HttpGet, AllowAnonymous, ValidateAntiForgeryToken, and ActionName.
MyController
.Calling(c => c.MyAction(With.Empty())) // Provides no value for the action parameter.
.ShouldHave()
.ActionAttributes(attributes => attributes
.RestrictingForHttpMethod(HttpMethod.Get)
.AllowingAnonymousRequests()
.ValidatingAntiForgeryToken()
.ChangingActionNameTo("AnotherAction"));
```

### View Component Tests

All applicable methods are available on the view component testing API too:

```c#
// View component integration test.
MyViewComponent
.Instance(instance => instance
.WithSession(session => session
.WithEntry("MySession", "MySessionValue"))
.WithData(data => data
.WithEntities(entities => entities
.AddRange(MyDataProvider.GetMyModels()))))
.InvokedWith(c => c.InvokeAsync(1))
.ShouldHave()
.ViewBag(viewBag => viewBag
.ContainingEntry("MyItems", 10)
.ContainingEntry("MyViewBagName", "MyViewBagValue"))
.AndAlso()
.ShouldReturn()
.View()
.WithModelOfType();

// View component unit test.
MyViewComponent
.Instance(instance => instance
.WithDependencies(
serviceMock,
anotherServiceMock,
From.Services())) // Provides a global service.
.InvokedWith(c => c.InvokeAsync(1))
.ShouldReturn()
.View();
```

### Arrange, Act, Assert (AAA) Tests

**MyTested.AspNetCore.Mvc** is fully compatible with the AAA testing methodology:

```c#
// Without breaking the fluent API.

MyMvc

// Arrange
.Controller()
.WithHttpRequest(request => request
.WithFormField("MyFormField", "MyFormFieldValue"))
.WithSession(session => session
.WithEntry("MySession", sessionId))
.WithUser()
.WithRouteData() // Populates the controller route data.
.WithData(data => data
.WithEntities(entities =>
AddData(sessionId, entities)))

// Act
.Calling(c => c.MyAction(
From.Services(), // Action injected services can be populated with this call.
new MyModel { Id = id },
CancellationToken.None))

// Assert
.ShouldReturn()
.Redirect(result => result
.To(c => c.AnotherAction(
With.No(),
id)));

// With variables.

// Arrange
var controller = MyController
.Instance()
.WithUser(username, new[] { role })
.WithData(MyTestData.GetData());

// Act
var call = controller.Calling(c => c.MyAction(id));

// Assert
call
.ShouldReturn()
.Json(result => result
.WithModelOfType()
.Passing(model => model.Id == id));
```

### Various Test Examples

Just random **MyTested.AspNetCore.Mvc** assertions:

```c#
// Tests whether model state error exists by using a lambda expression
// with specific tests for the error messages,
// and tests whether the action returns view with the same request model.
MyMvc
.Controller()
.Calling(c => c.MyAction(myRequestWithErrors))
.ShouldHave()
.ModelState(modelState => modelState
.For()
.ContainingNoErrorFor(m => m.NonRequiredProperty)
.AndAlso()
.ContainingErrorFor(m => m.RequiredProperty)
.ThatEquals("The RequiredProperty field is required."))
.AndAlso()
.ShouldReturn()
.View(myRequestWithErrors);

// Tests whether the action throws an exception
// of a particular type and with a particular error message.
MyMvc
.Controller()
.Calling(c => c.MyActionWithException())
.ShouldThrow()
.Exception()
.OfType()
.AndAlso()
.WithMessage()
.ThatEquals("My exception message");

// Tests whether the action return OK result
// and writes to the response specific content type,
// custom header, and custom cookie.
MyMvc
.Controller()
.Calling(c => c.MyAction())
.ShouldHave()
.HttpResponse(response => response
.WithContentType(ContentType.ApplicationJson)
.ContainingHeader("MyHeader", "MyHeaderValue")
.ContainingCookie(cookie => cookie
.WithName("MyCookie")
.WithValue("MyCookieValue")
.WithSecurity(true)
.WithHttpOnly(true)
.WithDomain("mydomain.com")
.WithExpiration(myDateTimeOffset)
.WithPath("/")))
.AndAlso()
.ShouldReturn()
.BadRequest();
```

## Package Installation

You can install this library using [NuGet](https://www.nuget.org/packages/MyTested.AspNetCore.Mvc.Universe) into your test project (or reference it directly in your `.csproj` file). Currently **MyTested.AspNetCore.Mvc** is fully compatible with ASP.NET Core MVC 3.1.0 and all older versions available on the official NuGet feed.

```powershell
Install-Package MyTested.AspNetCore.Mvc.Universe
```

This package will include all available assertion methods in your test project, including ones for authentication, database, session, caching and more. If you want only the MVC related features, install `MyTested.AspNetCore.Mvc`. Additionally, if you prefer, you can be more specific by including only some of the packages:

- `MyTested.AspNetCore.Mvc.Configuration` - Contains setup and assertion methods for configurations
- `MyTested.AspNetCore.Mvc.Controllers` - Contains setup and assertion methods for controllers
- `MyTested.AspNetCore.Mvc.Controllers.Attributes` - Contains setup and assertion methods for controller attributes
- `MyTested.AspNetCore.Mvc.Controllers.ActionResults` - Contains setup and assertion methods for controller API action results
- `MyTested.AspNetCore.Mvc.Controllers.Views` - Contains setup and assertion methods for controller view features
- `MyTested.AspNetCore.Mvc.Controllers.Views.ActionResults` - Contains setup and assertion methods for controller view action results
- `MyTested.AspNetCore.Mvc.Models` - Contains setup and assertion methods for responses and view models
- `MyTested.AspNetCore.Mvc.Routing` - Contains setup and assertion methods for routes
- `MyTested.AspNetCore.Mvc.Core` - Contains setup and assertion methods for MVC core features
- `MyTested.AspNetCore.Mvc.Pipeline` - Contains setup methods for pipeline tests
- `MyTested.AspNetCore.Mvc.TempData` - Contains setup and assertion methods for `ITempDataDictionary`
- `MyTested.AspNetCore.Mvc.ViewData` - Contains assertion methods for `ViewDataDictionary` and dynamic `ViewBag`
- `MyTested.AspNetCore.Mvc.ViewComponents` - Contains setup and assertion methods for view components
- `MyTested.AspNetCore.Mvc.ViewComponents.Attributes` - Contains setup and assertion methods for view component attributes
- `MyTested.AspNetCore.Mvc.ViewComponents.Results` - Contains setup and assertion methods for view component results
- `MyTested.AspNetCore.Mvc.ViewFeatures` - Contains setup and assertion methods for MVC view features
- `MyTested.AspNetCore.Mvc.Http` - Contains setup and assertion methods for HTTP context, request and response
- `MyTested.AspNetCore.Mvc.Authentication` - Contains setup methods for `ClaimsPrincipal`
- `MyTested.AspNetCore.Mvc.ModelState` - Contains setup and assertion methods for `ModelStateDictionary` validations
- `MyTested.AspNetCore.Mvc.DataAnnotations` - Contains setup and assertion methods for data annotation validations
- `MyTested.AspNetCore.Mvc.EntityFrameworkCore` - Contains setup and assertion methods for `DbContext`
- `MyTested.AspNetCore.Mvc.DependencyInjection` - Contains setup methods for dependency injection services
- `MyTested.AspNetCore.Mvc.Caching` - Contains setup and assertion methods for `IMemoryCache`
- `MyTested.AspNetCore.Mvc.Session` - Contains setup and assertion methods for `ISession`
- `MyTested.AspNetCore.Mvc.Options` - Contains setup and assertion methods for `IOptions`
- `MyTested.AspNetCore.Mvc.Helpers` - Contains additional helper methods for easier assertions

After the downloading is complete, just add `using MyTested.AspNetCore.Mvc;` to your source code and you are ready to test in the most elegant and developer friendly way.

```c#
using MyTested.AspNetCore.Mvc;
```

## Versioning

**MyTested.AspNetCore.Mvc** follows the ASP.NET Core MVC versions with which the testing framework is fully compatible. Specifically, the *major* and the *minor* versions will be incremented only when the MVC framework has a new official release. For example, version 3.1.\* of the testing framework is fully compatible with ASP.NET Core MVC 3.1.\*, version 2.2.\* is fully compatible with ASP.NET Core MVC 2.2.\*, version 1.0.15 is fully compatible with ASP.NET Core MVC 1.0.\*, and so on.

The public interface of **MyTested.AspNetCore.Mvc** will not have any breaking changes when the version increases (unless entirely necessary).

## License

Code by Ivaylo Kenov. Copyright 2015-2022 Ivaylo Kenov ([https://docs.mytestedasp.net/](https://docs.mytestedasp.net/))

**MyTested.AspNetCore.Mvc** is intended to be used in both open-source and commercial environments. To allow its use in as many
situations as possible, **MyTested.AspNetCore.Mvc** is dual-licensed. You may choose to use **MyTested.AspNetCore.Mvc** under
either the `Apache License, Version 2.0`, or the `Microsoft Public License (Ms-PL)`. These licenses are essentially
identical, but you are encouraged to evaluate both to determine which best fits your intended use.

See the [LICENSE](https://github.com/ivaylokenov/MyTested.AspNetCore.Mvc/blob/master/LICENSE) for detailed information.

## Any Questions, Comments or Additions?

If you have a feature request or bug report, leave an issue on the [issues page](https://github.com/ivaylokenov/MyTested.AspNetCore.Mvc/issues) or send a [pull request](https://github.com/ivaylokenov/MyTested.AspNetCore.Mvc/pulls). For general questions and comments, use the [StackOverflow](http://stackoverflow.com/) forum.