Answer the question
In order to leave comments, you need to log in
How to write an nUnit test for an ASP.NET controller that works with a Task?
Questions in the comments at the end of the test.
Minimal example. There is a base. The database has a model. Working with the model through EF Core
class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public interface IUserService
{
public void Add(User value);
}
public class UserService : IUserService
{
private readonly IApplicationContext context;
public UserService(IApplicationContext context) => this.context = context;
public void Add([FromBody] User value)
{
context.Users.Add(value);
context.SaveChanges();
}
}
public interface IApplicationContext
{
public DbSet<User> Users { get; set; }
public void SaveChanges();
}
public class UsersController : ControllerBase
{
private readonly IUserService userService;
public UsersController(IUserService service) => userService = service;
[HttpPost]
public async Task<IActionResult> Post([FromBody] User value)
{
userService.Add(value);
return Ok(value);
}
}
public class UsersControllerTests
{
[Test]
public void AddTest()
{
var mock = new Mock<IUserService>();
mock.Setup(service=>service.Add(new User()); // что писать внутри Add?
var controller = new UsersController(mock.Object);
var result = controller.Add(new User()); // Что писать внутри этого Add? Как он коррелирует с предыдущим Add?
// Что вообще писать на этапе Assert?
}
private List<User> GetTestUsers()
{
var users = new List<User>
{
new User { Id=1, Name="Tom" },
new User { Id=2, Name="Alice" },
new User { Id=3, Name="Sam" },
new User { Id=4, Name="Kate" }
};
return users;
}
}
Answer the question
In order to leave comments, you need to log in
Depends on what library for mocks you use, but most likely:
1. in the top mock you write with what argument the method of this service is expected to be called
2. then you call the controller method with some parameter (what you want to test)
3. In At the end, you make assertions, with the help of which you can make sure that everything worked out for you as it should.
In this case like this:
var user = new User();
var mock = new Mock<IUserService>();
mock.Setup(service=>service.Add(user));
var controller = new UsersController(mock.Object);
var result = (OkObjectResult) await controller.Add(user); // await не забываем
Assert.Equals(user, result.Value); // Ассерт, что контроллер вернул что ожидали
mock.Verify(x=>x.Add(user)); //Ассерт, что был вызван метод мока
Of course, I'm sure I'll get beaten here, but I'm usually against unit testing controllers. I think this is a waste of time, because in fact, I believe that unit tests are tests for business logic. And it should not be in the controller. In most cases, when testing a controller, you will be testing the correct operation of the framework, and this has already been done for you.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question