【问题标题】:Getting exception with Moq when trying to test Task尝试测试任务时出现最小起订量异常
【发布时间】:2019-04-09 23:39:30
【问题描述】:

我正在尝试在异步调用中使用 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: '模拟上的以下设置 'Mock<00000001>

&lt;&gt;

&lt;&gt;

    标签: c# .net unit-testing testing moq


    【解决方案1】:

    我们通常不必模拟不返回任何接口的方法,除非我在您的问题中遗漏了某些内容。

    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);
        }
    }
    

    【讨论】:

    • 这就是他得到例外的原因吗?
    • Castle 某些版本的起订量存在问题。 OP 的以下代码适用于 Moq 4.10.0Castle.Core 4.3.1repositoryMock.Setup(repo =&gt; repo.CreateAsync(It.IsAny&lt;Aggregate&gt;())).Returns(Task.CompletedTask).Verifiable();
    • @Win ,两个版本我都试过了。主线程中的那个没有调用 CreateAsync。第二个我已经替换为 repositoryMock.Setup(repo => repo.CreateOrderAsync(It.IsAny())).Returns(Task.CompletedTask).Verifiable(); Arrange .... 和 repositoryMock.VerifyAll();断言。得到同样的异常
    • @MCR 我不能说MoqCastle 的哪个版本有问题。您要设置返回Task 的方法的主要原因是验证调用。所以,你可以像我的回答一样明确地验证。
    【解决方案2】:

    我认为您的问题根本不在于起订量设置。问题是单元测试使用Task.Run() 运行有意义的代码,这会产生一个新线程。然后回到原始线程,您立即测试是否已满足最小起订量设置。由于被测代码是在不同的线程上启动的,因此成功测试很有可能在被测代码执行之前进行。

    您应该更改您的单元测试以使用 async & await 运行测试方法,而不是分离一个新线程。请注意,测试用例的签名从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();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-09-21
      • 2016-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-23
      • 2014-06-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多