问题描述
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容器来为你处理。
,如何模拟在方法内部创建的变量?
据我所知,你不能。在方法内部声明的变量仅存在于该方法中,因此无法在方法外部影响/操纵该变量。
也就是说,有一些方法可以实现您想要的,同时仍然遵循依赖注入实践。
以下是我个人会采取的步骤:
- 为
Discount
创建一个接口(如果您还没有这样做的话)。让我们称之为IDiscount
。 - 创建一个可以生产
IDiscount
的工厂。它的界面可能如下所示:
public interface IDiscountFactory
{
IDiscount CreateDiscount();
}
(抱歉,出于某种原因,代码示例布局对我来说是砖块,无法让它工作。编辑:如果我也评论阻止它,至少它也会进行代码格式化)
- 将此工厂注入您的类中,将其存储在
private readonly
变量中,并在您可以调用的CalculateShippingCost
方法中:var discount = _discountFactory.CreateDiscount();
这样实际的 Discount
只在您的方法中使用,但您仍然可以模拟 IDiscountFactory
(因此它产生的 IDiscount
)