如何模拟在方法中创建的变量 - Moq

问题描述

Class Myclass
{
   public void CalculateShippingCost()
 {
    /// Some line of codes.

     var discount= new discount();
     discount.Getdiscount();
     
      /// Some other functionality 
  }
}

在这里我想模拟 discount.Getdiscount() 调用,因为它进行服务调用。而且我不想在此方法之外公开此折扣对象。

解决方法

如您所见,在方法中包含 new 语句会使对其进行单元测试变得困难。这种情况下通常要做的就是像这样将依赖注入到类中

正如 Mark 在评论中指出的那样,您不能只是模拟 Discount,因为您不能有 2 个同名的类。所以你可以做的是创建一个接口来定义 Discount 的作用。那么您真正的 Discount 类和您的模拟都可以实现该接口。

MyClass 类中,您依赖于接口而不是类。

interface IDiscount 
{
    void GetDiscount();
}

Class Myclass
{
   private readonly IDiscount _discount;
   public Myclass(IDiscount discount) 
   {
      _discount = discount;
   }
   public void CalculateShippingCost()
 {
    /// Some line of codes.
     _discount.GetDiscount();
    
      /// Some other functionality 
  }
}

通过这种方式,您可以创建 IDiscount 接口的模拟,并在实例化时将其传递给 MyClass

如果你有少量的类,你可以手动完成这个依赖注入。如果你有很多类,可以考虑使用一个DI容器来为你处理。

,

如何模拟在方法内部创建的变量?

据我所知,你不能。在方法内部声明的变量仅存在于该方法中,因此无法在方法外部影响/操纵该变量。

也就是说,有一些方法可以实现您想要的,同时仍然遵循依赖注入实践。

以下是我个人会采取的步骤:

  1. Discount 创建一个接口(如果您还没有这样做的话)。让我们称之为IDiscount
  2. 创建一个可以生产 IDiscount 的工厂。它的界面可能如下所示:
public interface IDiscountFactory
{
   IDiscount CreateDiscount();
}

(抱歉,出于某种原因,代码示例布局对我来说是砖块,无法让它工作。编辑:如果我也评论阻止它,至少它也会进行代码格式化)

  1. 将此工厂注入您的类中,将其存储在 private readonly 变量中,并在您可以调用的 CalculateShippingCost 方法中:var discount = _discountFactory.CreateDiscount();

这样实际的 Discount 只在您的方法中使用,但您仍然可以模拟 IDiscountFactory(因此它产生的 IDiscount

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...