简体   繁体   English

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

[英]Can I mock object which is impossible to instantiate?

I am using some COM library in my C# which is bound to particular hardware and doesn't work without it. 我在C#中使用了一些COM库,该库绑定到特定的硬件,没有它就无法工作。 On development/testing computer I don't have that hardware. 在开发/测试计算机上,我没有该硬件。 The method which is using library looks like this: 使用库的方法如下所示:

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

The question is, can I mock HWSysManager for test method and how? 问题是,我可以模拟HWSysManager作为测试方法吗? There are few methods only in HWSysManager and it wouldn't be problem to simulate their functionality for test. 仅在HWSysManager只有很少的方法,并且模拟它们的功能进行测试不会有问题。 A tiny example would be great on how to mock it, if it's possible at all. 如果有可能的话,一个很小的例子将是如何模拟它的好方法。

You can use the adapter pattern here. 您可以在此处使用适配器模式。

Create an interface named IHWSysManager 创建一个名为IHWSysManager的接口

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

The real implementation class just delegates the work to the library: 真正的实现类仅将工作委托给库:

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

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

Use the interface in your code like this: 使用代码中的接口,如下所示:

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

Now you can mock your IHWSysManager interface with mock frameworks or you can create a stub class yourself. 现在,您可以使用模拟框架模拟IHWSysManager接口,也可以自己创建存根类。

You can use Typemock Isolator for faking HWSysManager. 您可以使用Typemock隔离器来伪造HWSysManager。

For your example, you can do the following: 对于您的示例,您可以执行以下操作:

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

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

And then, you can pass this faked manager to ProcessBias(IHWSysManager systemManager, string hwPath) as an argument. 然后,您可以将此伪造的管理器作为参数传递给ProcessBias(IHWSysManager systemManager, string hwPath)

As you said, you can simulate a few methods from IHWSysManager. 如您所说,您可以从IHWSysManager模拟一些方法。 So, me advice is to set up the behavior of this manager's methods using DoInstead(): 因此,我的建议是使用DoInstead()设置此管理器方法的行为:

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

You can look here for more information. 您可以在这里查看更多信息。 I think, it can be really useful for you. 我认为,这对您真的很有用。

I suppose you should create HWSysManager(or some other name) class to your Mock cases, add there some wanted methods and then mock them. 我想您应该为您的Mock案例创建HWSysManager(或其他名称)类,在其中添加一些有用的方法,然后对它们进行模拟。 For example: 例如:

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

and then setup: 然后设置:

    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
    }

Then to use your Mocked object just use the 'object' property: 然后,要使用Mocked对象,只需使用'object'属性:

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

In case above your methods/properties have to be virtual. 如果以上情况,您的方法/属性必须是虚拟的。

You can use interfaces also, in your case: 您也可以使用接口:

    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);
    }

All features of this Mock library are described here: https://github.com/Moq/moq4/wiki/Quickstart 该Mock库的所有功能在此处进行了描述: https : //github.com/Moq/moq4/wiki/Quickstart

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 用无法修改的类的私有构造函数模拟对象 - Mock an object with a private constructor of a class which I can't modify 我想在另一个被破坏的 object 的位置实例化一个 object - I want to instantiate an object at the location of another object which is destroyed 我可以从字符串开始并实例化该字符串的对象吗? - Can I start with a string and instantiate an object of that string? 为什么不能在函数中实例化对象 - Why can't I instantiate an object in a function 如何模拟返回的模拟对象的方法? - How can I mock a method of a returned mock object? Unity 我可以从可编写脚本的 object 实例化游戏 object 吗? - Unity can I instantiate a game object from a scriptable object? 安装模拟返回我发送给它的同一个对象? - Setup Mock to return the same object, which I send to it? 这是对适配器模式的正确使用吗? 我无法实例化该对象? - Is this a correct Use Of Adapter Pattern? I can't instantiate this object? 如何增加生成的 object(实例化)的 y? - How can I increase the y of the spawned object (Instantiate)? 我需要从两个类继承(这在C#中是不可能的)任何人都可以推荐一种不同的方式吗? - I need to inherit from two classes (which is impossible in C#) can anyone recommend a different way of doing this?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM