如何使用不传递给真实对象的模拟

问题描述 投票:0回答:1

我有服务CarTankService,如下所示。它具有我要测试的Add方法。更详细地说,我想检查是否达到AddTank (inside Add)

public class CarTankService : ICarTankService
{
    private readonly ITankQuery _tankQuery;
    private readonly CarClient _carClient;

    public CarTankService(ITankQuery tankQuery)
    {
        _tankQuery = tankQuery;
        _carClient = new CarClient();
    }

    public ObservableCollection<CarTank> GetTanks() => _carClient.Tanks;

    public void GenerateNewList() => _carClient.GenerateNewTanksList();

    public virtual void Add(CarTank tank)
    {
        if (_tankQuery.isExist(tank.Number)) throw new OwnException()

        _carClient.AddTank(tank);
    }

    public virtual void Remove(CarTank tank) => _carClient.RemoveCarTank(tank);
}

这是我的测试方法类:

[TestFixture]
class CarTankServiceTests
{
    private Mock<ITankQuery> TankQuery { get; set; }
    private ICarTankService CarTankService { get; set; }
    private Mock<CarClient> CarClient { get; set; }

    [SetUp]
    public void SetUp()
    {
        TankQuery = new Mock<ITankQuery>();
        CarClient = new Mock<CarClient>();
        CarTankService = new CarTankService(TankQuery.Object);
    }

    [Test]
    public void Add_NotExistReferenceNumber_AddTankReached()
    {
        TankQuery.Setup(uow => uow.isExist(It.IsAny<int>())).Returns(false);

        CarTankService.Add(new CarTank());

        CarClient.Verify(uow => uow.AddTank(It.IsAny<ClientTank>()),Times.Once);
    }
}

CarClient.Verify等于AddTank总是表明它在测试中是0 occurence,在这种情况下不正确。我不确定,但是我认为这是因为CarClient模型类,因为它不是直接插入到我的服务中,它始终显示为0。是吗?有测试的选项吗?

c# nunit
1个回答
0
投票

如果模拟CarClient,则必须设置要在测试中使用的所有方法(此处为AddTank)。在您的代码中,我们有两个CarClient实例,一个在您的测试中模拟,另一个在您的CarTankService的构造函数中初始化。因此,您在验证模拟的情况时正在调用后一种情况。

如果将CarClient转换为接口并注入接口,则解决方案是这样的:

[TestFixture]
class CarTankServiceTests
{
    private Mock<ITankQuery> TankQuery { get; set; }
    private ICarTankService CarTankService { get; set; }
    private Mock<CarClient> CarClient { get; set; }

    [SetUp]
    public void SetUp()
    {
        TankQuery = new Mock<ITankQuery>();
        CarClient = new Mock<CarClient>();
        CarTankService = new CarTankService(TankQuery.Object);
    }

    [Test]
    public void Add_NotExistReferenceNumber_AddTankReached()
    {
        TankQuery.Setup(uow => uow.isExist(It.IsAny<int>())).Returns(false);

        CarTankService.Add(new CarTank());

        CarClient.Setup(a=>a.AddTank(/*write you loginc*/));
        CarClient.Verify(uow => uow.AddTank(It.IsAny<ClientTank>()),Times.Once);
    }
}

这里有更多解释:

[当您在测试中编写CarTankService = new CarTankService(TankQuery.Object);时,它会在您的类(_carClient = new CarClient();)上创建一个新实例,因此该类具有其自己的实例,而测试类也具有它自己的实例(CarClient = new Mock<CarClient>();),该类将被模拟。这行代码CarTankService.Add(new CarTank());将槽添加到类的实例中,而在测试中,您正在验证没有槽(CarClient.Verify(uow => uow.AddTank(It.IsAny<ClientTank>()),Times.Once);)的测试类的实例。

© www.soinside.com 2019 - 2024. All rights reserved.