C# 如何将转换接口类型转换为具体类型
我试图模拟ManagementObjectSearcher类,并创建了一个IManagementInfo接口,那么如何将该接口转换为ManagementObjectSearcher类 这将为我创建一个空信息对象C# 如何将转换接口类型转换为具体类型,c#,unit-testing,C#,Unit Testing,我试图模拟ManagementObjectSearcher类,并创建了一个IManagementInfo接口,那么如何将该接口转换为ManagementObjectSearcher类 这将为我创建一个空信息对象 ManagementObjectSearcher s = new ManagementObjectSearcher(); IManagementInfo info =IManagementInfo(s); 这给了我运行时错误无法类型转换您不能这样做。您想这样做以便编写单元测试吗?如果
ManagementObjectSearcher s = new ManagementObjectSearcher();
IManagementInfo info =IManagementInfo(s);
这给了我运行时错误无法类型转换您不能这样做。您想这样做以便编写单元测试吗?如果您试图模拟一个您无法控制的类,那么您必须将其包装到另一个类中
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();
}
然后,代码将接受包装器或模拟对象。您可以使用IManagementInfo界面创建模拟。您不能这样做。您想这样做以便编写单元测试吗?如果您试图模拟一个您无法控制的类,那么您必须将其包装到另一个类中
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();
}
然后,代码将接受包装器或模拟对象。您可以使用IManagementInfo界面创建模拟。它看起来好像您正试图包装第三方/系统对象以帮助单元测试 说你的出发点是
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中创建一个依赖项,并存储一个我们每次调用的副本。无论哪种方式,我们都无法控制输出,这使得单元测试变得混乱
我们需要为它创建一个代理
一,。为我们需要的成员定义一个接口
最有可能的是,我们不需要使用wrappee的所有成员,因此只需要在接口中包含我们关心的那些成员
public interface IDependencyProxy {
string Foo();
}
二,。创建代理类
然后,我们创建一个代理类来包装依赖项并实现接口。同样,我们可以在开始时创建,也可以逐个调用创建
public class DependencyProxy : IDependencyProxy {
public string Foo() {
return new Dependency.Foo();
}
}
三,。根据接口定义我们的客户机代码
我们稍微修改了客户端代码,以使用IDependencyProxy接口而不是依赖项。有几种方法可以做到这一点。我通常使用一个内部的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();
}
}
这允许我们为调用系统对象的生产代码创建默认行为,并允许我们模拟单元测试的结果
[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());
}
看起来您正试图包装第三方/系统对象以帮助单元测试 说你的出发点是
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中创建一个依赖项,并存储一个我们每次调用的副本。无论哪种方式,我们都无法控制输出,这使得单元测试变得混乱
我们需要为它创建一个代理
一,。为我们需要的成员定义一个接口
最有可能的是,我们不需要使用wrappee的所有成员,因此只需要在接口中包含我们关心的那些成员
public interface IDependencyProxy {
string Foo();
}
二,。创建代理类
然后,我们创建一个代理类来包装依赖项并实现接口。同样,我们可以在开始时创建,也可以逐个调用创建
public class DependencyProxy : IDependencyProxy {
public string Foo() {
return new Dependency.Foo();
}
}
三,。根据接口定义我们的客户机代码
我们稍微修改了客户端代码,以使用IDependencyProxy接口而不是依赖项。有几种方法可以做到这一点。我通常使用一个内部的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();
}
}
这允许我们为调用系统对象的生产代码创建默认行为,并允许我们模拟单元测试的结果
[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());
}
密码没有它我如何帮助您?ManagementObjectSearcher是否实现了IManagementInfo接口?@JamesB:不,它没有。它的.net类代码??没有它我如何帮助您?ManagementObjectSearcher是否实现了IManagementInfo接口?@JamesB:不,它没有。它是.net类所以现在在你的代码中调用ManagementObjectSearcher管理信息对我来说很有意义努力实现上面提到的想要谢谢你的输入:没问题!如果这解决了您的问题,请将其标记为正确的解决方案。因此,现在在您的代码管理信息中调用ManagementObjectSearcher对我来说很有意义尝试实现上面所说的想要感谢您的输入:没问题!如果这解决了您的问题,请将其标记为正确的解决方案。