1

我正在尝试模拟ManagementObjectSearcher该类并创建了一个IManagementInfo接口,那么如何将接口转换为ManagementObjectSearcher该类?

 ManagementObjectSearcher s = new ManagementObjectSearcher();
 IManagementInfo info = s as IManagementInfo;

这为我创建了一个空信息对象

ManagementObjectSearcher s = new ManagementObjectSearcher();
 IManagementInfo info =IManagementInfo(s);

这给了我运行时错误(无法进行类型转换)

4

2 回答 2

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界面创建模拟。

于 2013-04-12T09:26:32.690 回答
0

看起来好像您正在尝试包装第 3 方/系统对象以帮助进行单元测试。

说你的出发点是

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.为我们需要的成员定义一个接口
很可能,我们不需要使用wrappee的所有成员,所以只在接口中包含我们关心的那些。

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 object),并允许我们模拟单元测试的结果。

[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());

}
于 2013-04-12T11:43:05.140 回答