Does any one know how to write a unit test (using xUnit) for the following Get() Method? Get() method is in the controller and returns list of all Categories:
public class CategoryController : Controller
{
private MyContext x;
public CategoryController(MyContext y)
{
x = y;
}
[HttpGet]
public ActionResult<IEnumerable<Category>> Get()
{
return x.Categories.ToList();
}
}
If you are using EFCore as ORM, you can use InMemory database for unit testing. There simple example:
[Fact]
public void TestGet()
{
_options = new DbContextOptionsBuilder<MyContext>()
.UseInMemoryDatabase(databaseName: "default")
.Options;
var context = new MyContext(_options);
context.EnsureSeed();
var controller = new CategoryController(context);
//Act
var results = controller.Get();
//Assert
Assert.NotNull(results);
Assert.True(results.Count > 0, "Expected to be greater than 0.");
}
Also you need implement EnsureSeed
method. Example:
public static void EnsureSeed(this MyContext dataContext)
{
//Check if database is created, if not - create
dataContext.Database.EnsureCreated();
var category = new Category()
{
Id = 1
};
dataContext.Categories.Add(category);
dataContext.SaveChanges();
}
From what I've seen and read the best way to unit test a controller function is to create an instance of the server host from your test setup and make requests directly to your endpoint - this will allow you test the transport layer of your application like the API contract and Http protocols. The following is an example implemented in.Net Core:
[Trait]
public class CategoryControllerTests : IClassFixture<WebApplicationFactory<Startup>>
{
// Startup - the entry point of most .net core project
private readonly WebApplicationFactory<Startup> _factory;
public CategoryControllerTests(WebApplicationFactory<Startup> factory)
{
// Any webhost config needed to run tests against the test
_factory = factory.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
// register any mock dependancies there - any dependencies in Startup.cs will hold unless overridden by a mock
services.AddScoped(x => new Mock() );
});
});
}
[Fact]
public async Task Get_ValidRequest_ReturnsData()
{
var client = _factory.CreateClient();
// Whatever routing protocol you use to define your endpoints
var url = "/category";
var response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsAsync<List<Category>>();
// Any asserts on your response
Assert.NotNull(content);
}
}
This is dependant on how you have setup the startup/initialisation of your project, it will allow you to test the project as though it were running in a production environment while letting you mock out any dependancies below the transport layer for a true unit test.
Note: the use of IClassFixture<WebApplicationFactory> - this will let you reuse an instance of WebApplicationFactory<Startup> for faster test execution; XUnit will inject this for you as part of the framework.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.