尝试测试任务时 Moq 出现异常
Getting exception with Moq when trying to test Task
我正在尝试在异步调用中使用 Moq (4.10),但我无法掌握它的窍门。
搜索如何执行此操作并找到我已尝试但无法正常工作的答案。
这是我的测试
public class Test
{
[Fact]
public void Test_Create()
{
var repositoryMock = new Mock<IRepository>();
repositoryMock
.Setup(repo => repo.CreateAsync(It.IsAny<Aggregate >()))
.Returns(Task.CompletedTask);
/// also tried this
/// => .Returns(Task.FromResult(default(object)))
/// and
/// => .Returns(Task.FromResult(false)));
var useCase = new CreateUseCase(repositoryMock.Object);
Task.Run(async () => { await useCase.HandleAsync(new CreateRequest()); });
repositoryMock.VerifyAll();
}
}
资源
How can I tell Moq to return a Task?
获取此异常
Moq.MockException: 'The following setups on mock
'Mock<.Repository.IRepository:00000001>' were not matched: IRepository
repo => repo.CreateAsync(It.IsAny < Aggregate>())
回购看起来像这样
public interface IRepository
{
Task CreateAsync(Aggregate aggregate);
}
用例
public class CreateUseCase : IUseCaseHandler<CreatRequest>
{
private IRepository _repository;
public CreateUseCase (IRepository repository)
{
_repository= repository?? throw new System.ArgumentNullException(nameof(repository));
}
public async Task HandleAsync(CreateRequest request, CancellationToken? cancellationToken = null)
{
Aggregate aggregate = new Aggregate();
aggregate.Create();
await _repository.CreateAsync(aggregate);
}
}
存储库
public sealed class OrderRepository : ProxyRepository<OrderAggregate>, IOrderRepository
{
public OrderRepository(IUnitOfWork unitOfWork, INotificationDispatcher eventHandler)
: base(unitOfWork, eventHandler)
{
}
async Task IRepository.CreateAsync(Aggregate aggregate)
{
await base.AddAsync(aggregate);
}
}
我做错了什么或遗漏了什么?
我们通常不必模拟没有 return 任何接口的方法,除非我在你的问题中遗漏了什么。
public class CreateUseCaseTests
{
[Fact]
public async Task HandleAsync_ShouldCreateRequest()
{
// Arrange
var repositoryMock = new Mock<IRepository>();
var sut = new CreateUseCase(repositoryMock.Object);
// Act
await sut.HandleAsync(new CreateRequest());
// Assert
repositoryMock.Verify(x => x.CreateAsync(It.IsAny<Aggregate>()), Times.Once);
}
}
我认为您的问题根本不在于最小起订量设置。问题是单元测试 运行 是使用 Task.Run()
的有意义的代码,它会产生一个新线程。然后回到原始线程,立即测试 Moq 设置是否已完成。由于被测代码是在不同的线程上启动的,因此很有可能在被测代码执行之前测试是否成功。
您应该将单元测试更改为 运行 使用异步和等待的测试方法,而不是分离出一个新线程。请注意,测试用例的签名从 void
更改为 async Task
,并且我们 await
我们正在测试的代码。
public class Test
{
[Fact]
public async Task Test_Create()
{
var repositoryMock = new Mock<IRepository>();
repositoryMock
.Setup(repo => repo.CreateAsync(It.IsAny<Aggregate >()))
.Returns(Task.CompletedTask);
var useCase = new CreateUseCase(repositoryMock.Object);
await useCase.HandleAsync(new CreateRequest());
repositoryMock.VerifyAll();
}
}
我正在尝试在异步调用中使用 Moq (4.10),但我无法掌握它的窍门。
搜索如何执行此操作并找到我已尝试但无法正常工作的答案。
这是我的测试
public class Test
{
[Fact]
public void Test_Create()
{
var repositoryMock = new Mock<IRepository>();
repositoryMock
.Setup(repo => repo.CreateAsync(It.IsAny<Aggregate >()))
.Returns(Task.CompletedTask);
/// also tried this
/// => .Returns(Task.FromResult(default(object)))
/// and
/// => .Returns(Task.FromResult(false)));
var useCase = new CreateUseCase(repositoryMock.Object);
Task.Run(async () => { await useCase.HandleAsync(new CreateRequest()); });
repositoryMock.VerifyAll();
}
}
资源
How can I tell Moq to return a Task?
获取此异常
Moq.MockException: 'The following setups on mock 'Mock<.Repository.IRepository:00000001>' were not matched: IRepository repo => repo.CreateAsync(It.IsAny < Aggregate>())
回购看起来像这样
public interface IRepository
{
Task CreateAsync(Aggregate aggregate);
}
用例
public class CreateUseCase : IUseCaseHandler<CreatRequest>
{
private IRepository _repository;
public CreateUseCase (IRepository repository)
{
_repository= repository?? throw new System.ArgumentNullException(nameof(repository));
}
public async Task HandleAsync(CreateRequest request, CancellationToken? cancellationToken = null)
{
Aggregate aggregate = new Aggregate();
aggregate.Create();
await _repository.CreateAsync(aggregate);
}
}
存储库
public sealed class OrderRepository : ProxyRepository<OrderAggregate>, IOrderRepository
{
public OrderRepository(IUnitOfWork unitOfWork, INotificationDispatcher eventHandler)
: base(unitOfWork, eventHandler)
{
}
async Task IRepository.CreateAsync(Aggregate aggregate)
{
await base.AddAsync(aggregate);
}
}
我做错了什么或遗漏了什么?
我们通常不必模拟没有 return 任何接口的方法,除非我在你的问题中遗漏了什么。
public class CreateUseCaseTests
{
[Fact]
public async Task HandleAsync_ShouldCreateRequest()
{
// Arrange
var repositoryMock = new Mock<IRepository>();
var sut = new CreateUseCase(repositoryMock.Object);
// Act
await sut.HandleAsync(new CreateRequest());
// Assert
repositoryMock.Verify(x => x.CreateAsync(It.IsAny<Aggregate>()), Times.Once);
}
}
我认为您的问题根本不在于最小起订量设置。问题是单元测试 运行 是使用 Task.Run()
的有意义的代码,它会产生一个新线程。然后回到原始线程,立即测试 Moq 设置是否已完成。由于被测代码是在不同的线程上启动的,因此很有可能在被测代码执行之前测试是否成功。
您应该将单元测试更改为 运行 使用异步和等待的测试方法,而不是分离出一个新线程。请注意,测试用例的签名从 void
更改为 async Task
,并且我们 await
我们正在测试的代码。
public class Test
{
[Fact]
public async Task Test_Create()
{
var repositoryMock = new Mock<IRepository>();
repositoryMock
.Setup(repo => repo.CreateAsync(It.IsAny<Aggregate >()))
.Returns(Task.CompletedTask);
var useCase = new CreateUseCase(repositoryMock.Object);
await useCase.HandleAsync(new CreateRequest());
repositoryMock.VerifyAll();
}
}