当你不想公开一个类的实例时,你如何创建一个模拟/替代?

时间:2016-12-23 20:06:55

标签: c# unit-testing mocking

我们说我有以下类LightbulbManager,它有Lightbulb个对象。在其构造函数中,它从外部资源(例如XML文件)加载Lightbulb

如果我通过属性公开myLightbulb,并且该属性是ILightbulbManager的一部分,那么我可以轻松地创建它的替代品。然而, 我不想将myLightbulb公开给此API的最终用户,因为他们可能会修改Lightbulb对象。另一种方法是添加SetLightbulb()功能,我可以使用该功能设置myLightbulb,但我也不希望最终用户拥有该功能。

所以我的问题是,如何通过创建IsLightbulbOn()的替代品来实际对myLightbulb进行单元测试?或者这是否表明我的代码设计很差?

class LightbulbManager : ILightbulbManager
{
    private Lightbulb myLightbulb;

    public LightbulbManager()
    {
        // Loads lightbulb information from an external resource.
    }

    public bool IsLightbulbOn()
    {
        return myLightbulb.IsOn;
    }
}

1 个答案:

答案 0 :(得分:3)

您可以创建一个ILightbulbFactory接口,其中包含两个实现该接口的类。一个用于从外部资源创建灯泡,另一个用于测试以创建替代品。然后将该工厂传递给LightbulbManager构造函数。

public interface ILightbulbFactory
{
    Lightbulb MakeLightbulb();
}

public class LightbulbFactory : ILightbulbFactory
{
    public Lightbulb MakeLightbulb()
    {
        Do your external resource load and return the object...
    }
}

public class LightbulbFactoryForTests : ILightbulbFactory
{
    public Lightbulb MakeLightbulb()
    {
        Create your lightbulb for testing...
    }
}

在构造函数中:

public LightbulbManager(ILightbulbFactory factory)
{
    myBulb = factory.MakeLightbulb();
}