I'm new to unit testing, so my problem is probably with my code and not the Moq framework, but here goes.
I'm using .Net Core with xUnit and the Moq framework, and I'm more or less following instructions from their documentation. I'm trying to test route api/user to get all users, and the issue was on asserting that the response was an ObjectResult containing <IEnumerable<User>>. No matter what I tried, result.Value was always null. The first assertion passes fine.
I set up a console project to debug this, and found something interesting. that value of the controller in the test method in Visual Studio is null. In VS Code, the value in the debugger shows Unknown Error: 0x00000....
Below is the test:
public class UserControllerTests {
[Fact]
public void GetAll_ReturnsObjectResult_WithAListOfUsers() {
// Arrange
var mockService = new Mock<IUserService>();
var mockRequest = new Mock<IServiceRequest>();
mockService.Setup(svc => svc.GetUsers(mockRequest.Object))
.Returns(new ServiceRequest(new List<User> { new User() }));
var controller = new UserController(mockService.Object);
// Act
var result = controller.GetAll();
// Assert
Assert.IsType<ObjectResult>(result);
Assert.IsAssignableFrom<IEnumerable<User>>(((ObjectResult)result).Value);
}
}
And here is the controller:
public class UserController : Controller {
private IUserService service;
public UserController(IUserService service) {
this.service = service;
}
[HttpGet]
public IActionResult GetAll() {
var req = new ServiceRequest();
service.GetUsers(req);
if(req.Errors != null) return new BadRequestObjectResult(req.Errors);
return new ObjectResult(req.EntityCollection);
}
}
And the Service Layer:
public interface IUserService {
IServiceRequest GetUsers(IServiceRequest req);
}
public class UserService : IUserService {
private IUserRepository repo;
public IServiceRequest GetUsers(IServiceRequest req) {
IEnumerable<User> users = null;
try {
users = repo.GetAll();
}
catch(MySqlException ex) {
req.AddError(new Error { Code = (int)ex.Number, Message = ex.Message });
}
finally {
req.EntityCollection = users;
}
return req;
}
}
public interface IServiceRequest {
IEnumerable<Object> EntityCollection { get; set; }
List<Error> Errors { get; }
void AddError(Error error);
}
public class ServiceRequest : IServiceRequest {
public IEnumerable<Object> EntityCollection { get; set; }
public virtual List<Error> Errors { get; private set; }
public ServiceRequest () { }
public void AddError(Error error) {
if(this.Errors == null) this.Errors = new List<Error>();
this.Errors.Add(error);
}
}
Like I said, it's probably something I'm doing wrong, I'm thinking in the mockService.Setup() but I'm not sure where. Help please?
service.GetUsers(req);suppose to do?reqis just a container for the<List>Userand/or<List>Error. So basically that line should just return an object containing a List of Users.reqvariable.