我正在尝试模拟ManagementObjectSearcher
类并创建了一个IManagementInfo
接口,那么我如何将接口转换为ManagementObjectSearcher
类?
ManagementObjectSearcher s = new ManagementObjectSearcher();
IManagementInfo info = s as IManagementInfo;
这会创建一个空信息对象
ManagementObjectSearcher s = new ManagementObjectSearcher();
IManagementInfo info =IManagementInfo(s);
这给了我运行时错误(不能强制转换)
答案 0 :(得分:4)
你做不到。你想这样做,你可以编写单元测试吗?如果你试图模拟一个你无法控制的类,那么你必须把它包装在另一个类中。
public class MyManagementObjectSearcherWrapper : IManagementInfo
{
public void TheMethodToMock()
{
var searcher = new ManagementObjectSearcher();
// The code you want to mock goes here
}
}
你运行这样的代码:
public void YourCode(IManagementInfo info)
{
info.TheMethodToMock();
}
然后,YourCode()将使用您的包装器或模拟对象。您可以使用IManagementInfo
界面创建模拟。
答案 1 :(得分:0)
看起来您正在尝试包装第三方/系统对象以帮助进行单元测试。
说你的出发点是
public class Dependency {
public string Foo() {
return "foo"; // machine, system, time, something else, dependent result
}
public string Bar() {
return "bar";
}
}
public class MySimpleClass {
public string MyFunc() {
return new Dependency().Foo();
}
}
[TestMethod]
public void TestSimple() {
var client = new MySimpleClass();
Assert.AreEqual("foo", client.MyFunc());
}
我们正在调用内部创建依赖项,因为我们正在考虑创建成本不如持有依赖项实例那么重要。这取决于具体情况。我们可以很容易地在ctor中创建一个Dependency并存储我们每次调用的副本。无论哪种方式,我们都无法控制输出,这使得单元测试变得混乱。
我们需要为它创建一个代理。
<强> 1。为我们需要的成员定义一个界面
最有可能的是,我们不需要使用包装的所有成员,因此只在接口中包含我们关心的那些成员。
public interface IDependencyProxy {
string Foo();
}
<强> 2。创建代理类
然后,我们创建一个包含依赖项和实现接口的代理类。同样,我们可以在开始时或逐个呼叫的基础上创建。
public class DependencyProxy : IDependencyProxy {
public string Foo() {
return new Dependency.Foo();
}
}
第3。根据界面定义我们的客户代码 我们稍微修改我们的客户端代码以使用IDependencyProxy接口而不是Dependency。有几种方法可以做到这一点。我通常使用一个内部ctor,它接受来自公共ctor的链接。 (使用[InternalsVisibleTo]允许单元测试看到它)
public class MyRevisedClass {
private readonly IDependencyProxy dependency;
public MyRevisedClass()
: this( new DependencyProxy()) {}
internal MyRevisedClass(IDependencyProxy dependency) {
this.dependency = dependency;
}
public string MyFunc() {
return dependency.Foo();
}
}
这允许我们生产代码的默认行为(调用System对象)并允许我们模拟单元测试的结果。
[TestMethod]
public void TestRevisedDefault() {
var client = new MyRevisedClass();
Assert.AreEqual("foo", client.MyFunc());
}
[TestMethod]
public void TestRevisedWithMockedDependency() {
var dep = new Mock<IDependencyProxy>();
dep.Setup(mk => mk.Foo()).Returns("bar");
var client = new MyRevisedClass(dep.Object);
Assert.AreEqual("bar", client.MyFunc());
}