我可以模拟无法实例化的对象吗?
Can I mock object which is impossible to instantiate?
我在我的 C# 中使用了一些 COM 库,它绑定到特定的硬件,没有它就无法工作。在 development/testing 计算机上我没有那个硬件。使用库的方法如下所示:
using HWSysManagerLib;
bool ProcessBias(HWSysManager systemManager, string hwPath)
{
int handle = systemManager.OpenConfiguration(hwPath);
...
// some magic goes here
// return result
}
问题是,我可以为测试方法模拟 HWSysManager
吗?如何模拟? HWSysManager
中只有很少的方法,模拟它们的功能进行测试不会有问题。如果可能的话,一个小例子会很好地说明如何模拟它。
我想你应该为你的模拟案例创建 HWSysManager(或其他名称)class,在其中添加一些想要的方法,然后模拟它们。例如:
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 对象只需使用 'object' 属性:
var hwSysInstance = hwSysManager.Object;
var result = hwSysInstance.ExampleReturnInMethod(2); //result will be 10 in this case - as we have mocked
如果以上情况,您的 methods/properties 必须是虚拟的。
您也可以使用接口,在您的情况下:
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
您可以在此处使用适配器模式。
创建一个名为 IHWSysManager
的接口
public interface IHWSysManager
{
int OpenConfiguration(string hwPath);
}
真正的实现class只是将工作委托给库:
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
界面,或者您可以自己创建一个存根 class。
您可以使用 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了解更多信息。我想,它对你真的很有用。
我在我的 C# 中使用了一些 COM 库,它绑定到特定的硬件,没有它就无法工作。在 development/testing 计算机上我没有那个硬件。使用库的方法如下所示:
using HWSysManagerLib;
bool ProcessBias(HWSysManager systemManager, string hwPath)
{
int handle = systemManager.OpenConfiguration(hwPath);
...
// some magic goes here
// return result
}
问题是,我可以为测试方法模拟 HWSysManager
吗?如何模拟? HWSysManager
中只有很少的方法,模拟它们的功能进行测试不会有问题。如果可能的话,一个小例子会很好地说明如何模拟它。
我想你应该为你的模拟案例创建 HWSysManager(或其他名称)class,在其中添加一些想要的方法,然后模拟它们。例如:
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 对象只需使用 'object' 属性:
var hwSysInstance = hwSysManager.Object;
var result = hwSysInstance.ExampleReturnInMethod(2); //result will be 10 in this case - as we have mocked
如果以上情况,您的 methods/properties 必须是虚拟的。
您也可以使用接口,在您的情况下:
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
您可以在此处使用适配器模式。
创建一个名为 IHWSysManager
public interface IHWSysManager
{
int OpenConfiguration(string hwPath);
}
真正的实现class只是将工作委托给库:
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
界面,或者您可以自己创建一个存根 class。
您可以使用 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了解更多信息。我想,它对你真的很有用。