我正在尝试编写使用Dll导入的类的单元测试用例,如下所示
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string name, string windowName);
为了测试该类,我想使用MOQ模拟上述语句,但无法弄清楚如何为它设置模拟。
还想知道上述内容是否可以实现..如果不是那么需要做些什么才能使其成为可测试的。
我知道要使这个类可测试,我们需要在这些语句上创建包装器,并且需要在单独的类中将它分开。
想知道是否还有其他选择来实现同样目标。
答案 0 :(得分:3)
实际上,您可以使用typemock Isolator来模拟导出的Dll中的方法,并且不会对代码进行任何不必要的更改。 你只需要导出Dll并模拟方法,就像任何其他静态方法一样, 例如:
public class ClassUnderTest
{
public bool foo()
{
if(Dependecy.FindWindow("bla","bla") == null)
{
throw new Exception();
}
return true;
}
}
public class Dependecy
{//imported method from dll
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string name, string windowName);
}
[TestMethod]
public void TestMethod1()
{
//setting a mocked behavior for when the method will be called
Isolate.WhenCalled(() => Dependecy.FindWindow("", "")).WillReturn(new IntPtr(5));
ClassUnderTest classUnderTest = new ClassUnderTest();
var res = classUnderTest.foo();
Assert.IsTrue(res);
}
您可以详细了解Pinvoked Methods here
答案 1 :(得分:1)
您无法模拟静态方法,只能模拟具有虚拟成员的接口或类。但是,您可以将方法包装为可以包装的虚拟方法:
interface StaticWrapper
{
InPtr WrapStaticMethod(string name, string windowName);
}
class MyUsualBehaviour : IStaticWrapper
{
public InPtr WrapStatic(string name, string windowName)
{
// here we do the static call from extern DLL
return FindWindow(name, widnowName);
}
}
但是,您现在可以模拟该接口而不是静态方法:
var mock = new Moq<IStaticWrapper>();
mock.Setup(x => x.WrapStatic("name", "windowName")).Returns(whatever);
此外,您没有在代码中调用extern方法,只调用了减少代码耦合到特定库的包装器。
有关进一步说明的信息,请参阅此链接:http://adventuresdotnet.blogspot.de/2011/03/mocking-static-methods-for-unit-testing.html