本文介绍了如何使用未传递给真实对象的模拟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have service CarTankService as shown below. It has Add method which i want to test. To be more detailed i would like to check whether AddTank (inside Add) will be reached.

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 for AddTank 在测试中总是显示 0 发生,在这种情况下这是不正确的.我不确定,但我认为这是因为 CarClient 模型类,因为它没有直接注入我的服务,它总是显示 0.我对吗?有没有测试的选项?

CarClient.Verify for AddTank always show it was 0 occurence in test, which in this case is not true. I am not sure but I think it's because CarClient model class because it's not injected directly insdie my service it always shows 0. AM i right? Is there any option to test it?

推荐答案

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

If you mock your CarClient you have to setup all methods you want to use in your test (here AddTank). In you code we have two CarClient instances, one is mocked in your test and another is initialized in your constructor of CarTankService. So, you are calling the latter case while verifying the mocked one.

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

If you convert the CarClient to an interface and inject it, The solution is something like this:

[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();) 被模拟.这行代码 CarTankService.Add(new CarTank()); 将坦克添加到类的实例中,而在您的测试中,您正在验证没有坦克的测试类的实例(CarClient.Verify(uow => uow.AddTank(It.IsAny()),Times.Once);).

When you write CarTankService = new CarTankService(TankQuery.Object); in your test, it creates a new instance on your class (_carClient = new CarClient();), so the class has it's own instance, while the test class has it own too (CarClient = new Mock<CarClient>();) which is mocked. This line of code CarTankService.Add(new CarTank()); adds the tank to the instance of class, while in your test, you are verifying the instance of test class which has no tank (CarClient.Verify(uow => uow.AddTank(It.IsAny<ClientTank>()),Times.Once);).

这篇关于如何使用未传递给真实对象的模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-12 15:15