我可以模拟无法实例化的对象吗?

时间:2015-10-03 07:03:41

标签: c# unit-testing mocking nunit

我在C#中使用了一些COM库,它与特定的硬件绑定,没有它就无法工作。在开发/测试计算机上,我没有那个硬件。使用库的方法如下所示:

using HWSysManagerLib;
bool ProcessBias(HWSysManager systemManager, string hwPath)
{
    int handle = systemManager.OpenConfiguration(hwPath);
    ...
    // some magic goes here
    // return result
}

问题是,我可以模拟HWSysManager测试方法吗?仅HWSysManager中的方法很少,模拟其测试功能不会有问题。如果可能的话,一个很小的例子就是如何嘲笑它。

3 个答案:

答案 0 :(得分:5)

您可以在此处使用适配器模式。

创建名为IHWSysManager

的界面
public interface IHWSysManager
{
    int OpenConfiguration(string hwPath);
}

真正的实现类只是将工作委托给库:

public class HWSysManagerImpl : IHWSysManager
{
    private HWSysManager _hwSysManager; //Initialize from constructor

    public int OpenConfiguration(string hwPath)
    {
        return _hwSysManager.openConfiguration(hwPath);
    }
}

使用代码中的界面:

bool ProcessBias(IHWSysManager systemManager, string hwPath)
{
    int handle = systemManager.OpenConfiguration(hwPath);
    ...
    // some magic goes here
    // return result
}

现在您可以使用模拟框架模拟IHWSysManager接口,或者您可以自己创建存根类。

答案 1 :(得分:1)

您可以使用Typemock Isolator伪造HWSysManager。

对于您的示例,您可以执行以下操作:

var fakeManager = Isolate.Fake.Instance<HWSysManager>();

Isolate.WhenCalled(() => fakeManager.OpenConfiguration("")).WillReturn(0);

然后,你可以将这个伪造的经理作为论据传递给ProcessBias(IHWSysManager systemManager, string hwPath)

正如您所说,您可以从IHWSysManager模拟一些方法。所以,我的建议是使用DoInstead()来设置这个管理器方法的行为:

Isolate.WhenCalled(() => fakeManager.OpenConfiguration("")).DoInstead(
    context =>
    {
        //Your simulation
    });

您可以查看here以获取更多信息。我想,它对你真的很有用。

答案 2 :(得分:-1)

我想你应该为你的模拟案例创建HWSysManager(或其他名称)类,添加一些想要的方法,然后模拟它们。例如:

    class HWSysManager
    {
        public virtual int ExampleReturnIntMethod(int a)
        {
            var someInt = 0;
            return someInt;
        }

然后设置:

    public void TestMethod()
    {
        Mock<HWSysManager> hwSysManager = new Mock<HWSysManager>();
        hwSysManager.Setup(x => x.ExampleReturnInMethod(It.IsAny<int> ())).Returns(10); //if parameter is any of int, return 10 in this case
    }

然后使用你的Mocked对象只需使用&#39;对象&#39;属性:

 var hwSysInstance = hwSysManager.Object;
 var result = hwSysInstance.ExampleReturnInMethod(2); //result will be 10 in this case - as we have mocked

如果上面的方法/属性必须是虚拟的。

您也可以使用接口:

    public interface HwsysManager
    {
        int OpenConfiguration(string hwPath);
    }

     public void TestMethod()
    {
      Mock<HwsysManager> hwsysManager = new Mock<HwsysManager>();

      hwsysManager.Setup(x => x.OpenConfiguration(It.IsAny<string>())).Returns(10);
    }

此Mock库的所有功能如下所述: https://github.com/Moq/moq4/wiki/Quickstart