即使在同一方法调用上同时验证Times.Once()和Times.Never()时,Moq测试也会通过

时间:2013-12-13 13:26:48

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

我正在使用Xunit来测试Create上的CarController方法,而我正在使用Moq来模拟我的CarRepository

然后我使用mockCarRepository.Verify(m => m.Create(It.IsAny<Car>()), Times.Once());检查我的存储库中的Create方法是否正在被调用。但无论我是否打电话,测试都会通过。

以下是我验证both that Create is called once AND that it is called never的完整示例。当我预料到失败时,我的测试就过去了。

using System;
using Moq;
using Xunit;
namespace Test
{
    public class CarTest
    {
        [Fact()]
        public async void CreateTest()
        {
            var mockCarRepository = new Mock<CarRepository>();
            var carController = new CarController(mockCarRepository.Object);
            carController.Create(new Car
            {
                Make = "Aston Martin",
                Model = "DB5"
            });
            mockCarRepository.Verify(m => m.Create(It.IsAny<Car>()), Times.Once());
            mockCarRepository.Verify(m => m.Create(It.IsAny<Car>()), Times.Never());
        }
    }

    public class CarController
    {
        private readonly CarRepository _repo;
        public CarController(CarRepository repo)
        {
            _repo = repo;
        }

        public void Create(Car car)
        {
            _repo.Create(car);
        }
    }

    public class Car
    {
        public virtual String Make { get; set; }
        public virtual String Model { get; set; }
    }

    public class CarRepository
    {
        public virtual void Create(Car car)
        {
            // DO SOMETHING
        }
    }
}

当我调试测试时,虽然它仍然通过,但我注意到抛出了以下异常:

A first chance exception of type 'Moq.MockException' occurred in Moq.dll

Additional information: 

Expected invocation on the mock should never have been performed, but was 1 times: m => m.Create(It.IsAny<Car>())

No setups configured.



Performed invocations:

CarRepository.Create(Test.Car)

我预计会遇到异常,因为我正在调用Create并验证Times.Never(),但我希望我的测试失败。我需要做些什么来实现这个目标?

更新事实证明问题在于我将我的测试标记为async - 删除导致它通过。但是我写的实际代码会调用async方法,所以现在我的问题是,如何在使用异步方法时验证方法是否被调用?

2 个答案:

答案 0 :(得分:3)

请参阅答案here,了解为什么async void测试方法在xUnit中不起作用的解释。

解决方案是为您的测试方法提供async Task签名。

已为xunit 2.0版添加了

async void功能,有关详细信息,请参阅here

答案 1 :(得分:2)

事实证明问题是我的测试方法被标记为async删除,导致它按预期工作。