C# 伪造在构造函数中创建的数据成员
我有以下课程:C# 伪造在构造函数中创建的数据成员,c#,unit-testing,mocking,C#,Unit Testing,Mocking,我有以下课程: public class ExampleClass { private readonly Service service; public ExampleClass() { service = new Service(); } private void ExecuteProcess() { var request = Transfer.RequestParameters; ser
public class ExampleClass
{
private readonly Service service;
public ExampleClass()
{
service = new Service();
}
private void ExecuteProcess()
{
var request = Transfer.RequestParameters;
service.SyncMethod(request);
}
}
我试图伪造构造函数中创建的私有只读服务
服务,因为我想忽略对服务.SyncMethod(request)
的调用。
有人知道我如何做到这一点吗?提供一个参数化构造函数,如下所示:
public ExampleClass(Service obj)
{
service = obj;
}
然后您可以模拟并将服务对象传递给上述构造函数&测试函数
还建议针对接口编写代码,在您的情况下,创建iSeries设备,并在服务中实现它。然后您可以将接口注入ExampleClass,而不是具体的实现。我认为您应该使用称为“依赖注入”的东西。这可以很容易地用Ninject或Unity来实现 结果是您没有在ExampleClass中创建服务,而是将IService类型的对象传递给构造函数 接口有一个SyncMethod方法 您可以让服务实现接口IService。您可以创建一个TestService或其他同样实现IService的东西 在TestService对象中,您可以使SyncMethod方法的一个空实现忽略它。您可以使用它来伪造服务实例和调用私有方法,例如:
[TestMethod]
public void TestMethod1()
{
Service faked = Isolate.Fake.NextInstance<Service>(Members.ReturnRecursiveFakes, ConstructorWillBe.Called);
ExampleClass exClass = new ExampleClass();
Isolate.WhenCalled(() => faked.SyncMethod(null)).IgnoreCall();
Isolate.Invoke.Method(exClass, "ExecuteProcess");
}
[TestMethod]
公共void TestMethod1()
{
服务伪造=隔离.false.NextInstance(Members.ReturnRecursiveFakes,构造函数willbe.Called);
ExampleClass=newExampleClass();
隔离.WhenCalled(()=>faked.SyncMethod(null)).IgnoreCall();
隔离.Invoke.Method(感叹号,“ExecuteProcess”);
}
当前状态下的类与依赖服务的耦合过于紧密,因此很难(但并非不可能)模拟依赖关系,以便能够单独测试该类
第一类应该依赖于抽象,而不是具体化。因此,将服务
抽象到接口后面,以便在单独维护和测试代码时更加灵活
比如说
public interface IService {
void SyncMethod(RequestParameters request);
}
public class Service : IService {
//..code removed for brevity
}
然后重构您的类,以遵循以下步骤。这种方法称为“构造函数注入”
在生产环境中,实际的依赖关系将在组合根目录中的依赖关系容器中注册,当解析类时,依赖关系将被实现并注入到依赖类中
这还允许在测试期间手动或使用您选择的模拟框架/工具使用模拟/伪造/存根。或者更好,使用接口(iSeries),因为您应该使用接口,DI.OP希望忽略对现有对象的服务调用。SyncMethod(请求)你们比我早几秒+祝你好运both@Neil:您在我编辑答案时发表了评论!:)@阿里:OP还呼吁伪造只读服务
public class ExampleClass {
private readonly IService service;
public ExampleClass(IService servic) {
this.service = service;
}
private void ExecuteProcess() {
var request = Transfer.RequestParameters;
service.SyncMethod(request);
}
}