【问题标题】:How to mock a variable that is created inside a method - Moq如何模拟在方法内创建的变量 - Moq
【发布时间】:2021-08-23 02:46:36
【问题描述】:
Class Myclass
{
   public void CalculateShippingCost()
 {
    /// Some line of codes.

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

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

【问题讨论】:

    标签: c# unit-testing mocking tdd moq


    【解决方案1】:

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

    正如 Mark 在 cmets 中指出的那样,您不能只模拟 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 容器来为你处理。

    【讨论】:

    • 这只能在GetDiscount 方法为virtual 时起作用,而在C# 中默认情况下不是这样。
    • @MarkSeemann 谢谢,马克。你说得对。我已将答案更新为依赖于接口。
    【解决方案2】:

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

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

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

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-24
      • 2014-12-06
      • 2011-04-17
      • 2017-10-14
      • 2017-01-15
      • 1970-01-01
      相关资源
      最近更新 更多