XUnit 测试最小起订量失败
XUnit Test Moq failing
我是 XUnit 和 Moq 的新手。我正在尝试一个简单的测试,但无法让它工作。
我有 7 个测试记录,想为我的测试添加第 8 个。
我的测试总是失败,原来是 7 条测试记录,而不是 8 条。
我已经按照下面设置了我的测试..
public class CreateHandlerTests
{
private readonly Mock<IUnitOfWork> _mockUnitOfWork;
private readonly Mock<IGenericRepository<ServerAccess>> _mockRepo;
public CreateHandlerTests()
{
_mockUnitOfWork = new Mock<IUnitOfWork>();
_mockRepo = new Mock<IGenericRepository<ServerAccess>>();
}
[Fact]
public async Task ServerAccess_Created()
{
var list = MockData.GetServerAccessList(); // 7 test records
_mockRepo.Setup(x => x.CountAsync()).ReturnsAsync(list.Count);
_mockRepo.Setup(x => x.Add(It.IsAny<ServerAccess>())).Callback<ServerAccess>(item => list.Add(item));
_mockUnitOfWork.Setup(x => x.Repository<ServerAccess>()).Returns(_mockRepo.Object);
var before = await _mockRepo.Object.CountAsync();
var sut = new CreateHandler(_mockUnitOfWork.Object);
await sut.Execute(new CreateCommand()
{
AccessMethod = "New server access method",
Description = "New description"
});
var after = await _mockRepo.Object.CountAsync();
// Assert
Assert.True(after==8);
}
...
}
似乎当我的命令处理程序添加记录时,我的 Mock IGenericRepository 中的 Add 方法没有被调用。
下面是我的 IUnitOfWork 界面
public interface IUnitOfWork
{
IGenericRepository<TEntity> Repository<TEntity>() where TEntity : BaseEntity;
Task<int> Complete();
}
这是我的命令处理程序实现
public class CreateHandler : ICommandHandler<CreateCommand>
{
private readonly IUnitOfWork _unitOfWork;
public CreateHandler(IUnitOfWork unitOfWork)
{
_unitOfWork = Guard.Against.Null(unitOfWork, nameof(unitOfWork));
}
public async Task Execute(CreateCommand command)
{
var serverAccess = new ServerAccess()
{
AccessMethod = command.AccessMethod,
Description = command.Description
};
_unitOfWork.Repository<ServerAccess>().Add(serverAccess);
await _unitOfWork.Complete();
}
}
我的模拟设置中是否遗漏了什么?
感谢任何帮助。
问题是因为您return使用固定值
_mockRepo.Setup(x => x.CountAsync()).ReturnsAsync(list.Count);
以上同
_mockRepo.Setup(x => x.CountAsync()).ReturnsAsync(7);
每次都会 return 7,因为它是用固定值设置的。
使用每次调用预期成员时都会调用的 function/delegate。
[Fact]
public async Task ServerAccess_Created() {
var list = MockData.GetServerAccessList(); // 7 test records
_mockRepo
.Setup(x => x.CountAsync())
.ReturnsAsync(() => list.Count); //delegate invoked each time
_mockRepo
.Setup(x => x.Add(It.IsAny<ServerAccess>()))
.Callback(ServerAccess item => list.Add(item)); //delegate invoked each time
_mockUnitOfWork
.Setup(x => x.Repository<ServerAccess>())
.Returns(_mockRepo.Object); //fixed value
int before = await _mockRepo.Object.CountAsync();
CreateHandler sut = new CreateHandler(_mockUnitOfWork.Object);
await sut.Execute(new CreateCommand() {
AccessMethod = "New server access method",
Description = "New description"
});
int after = await _mockRepo.Object.CountAsync();
// Assert
Assert.True(after == 8);
}
但是,上面的测试应该被简化以断言基于被测对象的实际预期行为
[Fact]
public async Task ServerAccess_Created() {
//Arrange
_mockUnitOfWork
.Setup(x => x.Repository<ServerAccess>())
.Returns(_mockRepo.Object);
CreateHandler sut = new CreateHandler(_mockUnitOfWork.Object);
//Act
await sut.Execute(new CreateCommand() {
AccessMethod = "New server access method",
Description = "New description"
});
// Assert
_mockRepo.Verify(x => x.Add(It.IsAny<ServerAccess>());
}
我是 XUnit 和 Moq 的新手。我正在尝试一个简单的测试,但无法让它工作。
我有 7 个测试记录,想为我的测试添加第 8 个。
我的测试总是失败,原来是 7 条测试记录,而不是 8 条。
我已经按照下面设置了我的测试..
public class CreateHandlerTests
{
private readonly Mock<IUnitOfWork> _mockUnitOfWork;
private readonly Mock<IGenericRepository<ServerAccess>> _mockRepo;
public CreateHandlerTests()
{
_mockUnitOfWork = new Mock<IUnitOfWork>();
_mockRepo = new Mock<IGenericRepository<ServerAccess>>();
}
[Fact]
public async Task ServerAccess_Created()
{
var list = MockData.GetServerAccessList(); // 7 test records
_mockRepo.Setup(x => x.CountAsync()).ReturnsAsync(list.Count);
_mockRepo.Setup(x => x.Add(It.IsAny<ServerAccess>())).Callback<ServerAccess>(item => list.Add(item));
_mockUnitOfWork.Setup(x => x.Repository<ServerAccess>()).Returns(_mockRepo.Object);
var before = await _mockRepo.Object.CountAsync();
var sut = new CreateHandler(_mockUnitOfWork.Object);
await sut.Execute(new CreateCommand()
{
AccessMethod = "New server access method",
Description = "New description"
});
var after = await _mockRepo.Object.CountAsync();
// Assert
Assert.True(after==8);
}
...
}
似乎当我的命令处理程序添加记录时,我的 Mock IGenericRepository 中的 Add 方法没有被调用。
下面是我的 IUnitOfWork 界面
public interface IUnitOfWork
{
IGenericRepository<TEntity> Repository<TEntity>() where TEntity : BaseEntity;
Task<int> Complete();
}
这是我的命令处理程序实现
public class CreateHandler : ICommandHandler<CreateCommand>
{
private readonly IUnitOfWork _unitOfWork;
public CreateHandler(IUnitOfWork unitOfWork)
{
_unitOfWork = Guard.Against.Null(unitOfWork, nameof(unitOfWork));
}
public async Task Execute(CreateCommand command)
{
var serverAccess = new ServerAccess()
{
AccessMethod = command.AccessMethod,
Description = command.Description
};
_unitOfWork.Repository<ServerAccess>().Add(serverAccess);
await _unitOfWork.Complete();
}
}
我的模拟设置中是否遗漏了什么?
感谢任何帮助。
问题是因为您return使用固定值
_mockRepo.Setup(x => x.CountAsync()).ReturnsAsync(list.Count);
以上同
_mockRepo.Setup(x => x.CountAsync()).ReturnsAsync(7);
每次都会 return 7,因为它是用固定值设置的。
使用每次调用预期成员时都会调用的 function/delegate。
[Fact]
public async Task ServerAccess_Created() {
var list = MockData.GetServerAccessList(); // 7 test records
_mockRepo
.Setup(x => x.CountAsync())
.ReturnsAsync(() => list.Count); //delegate invoked each time
_mockRepo
.Setup(x => x.Add(It.IsAny<ServerAccess>()))
.Callback(ServerAccess item => list.Add(item)); //delegate invoked each time
_mockUnitOfWork
.Setup(x => x.Repository<ServerAccess>())
.Returns(_mockRepo.Object); //fixed value
int before = await _mockRepo.Object.CountAsync();
CreateHandler sut = new CreateHandler(_mockUnitOfWork.Object);
await sut.Execute(new CreateCommand() {
AccessMethod = "New server access method",
Description = "New description"
});
int after = await _mockRepo.Object.CountAsync();
// Assert
Assert.True(after == 8);
}
但是,上面的测试应该被简化以断言基于被测对象的实际预期行为
[Fact]
public async Task ServerAccess_Created() {
//Arrange
_mockUnitOfWork
.Setup(x => x.Repository<ServerAccess>())
.Returns(_mockRepo.Object);
CreateHandler sut = new CreateHandler(_mockUnitOfWork.Object);
//Act
await sut.Execute(new CreateCommand() {
AccessMethod = "New server access method",
Description = "New description"
});
// Assert
_mockRepo.Verify(x => x.Add(It.IsAny<ServerAccess>());
}