我有以下课程:
public class ExampleClass
{
private readonly Service service;
public ExampleClass()
{
service = new Service();
}
private void ExecuteProcess()
{
var request = Transfer.RequestParameters;
service.SyncMethod(request);
}
}
我正在尝试伪造在构造函数中创建的private readonly Service
服务,因为我想忽略对service.SyncMethod(request)
的调用。
有谁知道我怎么能这样做?
答案 0 :(得分:2)
您可以使用Typemock's Isolator伪造Service实例并调用私有方法,例如:
[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");
}
答案 1 :(得分:1)
提供参数化构造函数,如下所示:
public ExampleClass(Service obj)
{
service = obj;
}
然后你可以模拟并将服务对象传递给上面的构造函数&amp;测试功能。
还建议对接口进行编码,在您的情况下,创建一个IService,在Service中实现它。然后,您可以将接口注入ExampleClass而不是具体实现。
答案 2 :(得分:1)
我认为你应该使用一种叫做“依赖注射”的东西。这可以通过Ninject或Unity轻松完成。
结果是您不在ExampleClass中创建服务,而是将类型为IService的对象传递给构造函数。
界面有一个方法SyncMethod。
您让Service实现接口IService。您创建一个TestService或同样实现IService的东西。
在TestService对象中,您可以对SyncMethod方法进行空实现以忽略它。
答案 3 :(得分:1)
您处于当前状态的类与依赖服务的耦合过于紧密,因此很难(但不是不可能)模拟依赖项以便能够单独测试该类。
首先应该依赖于抽象而不是结核。因此抽象接口后面的Service
,以便在单独维护和测试代码时更灵活。
例如
public interface IService {
void SyncMethod(RequestParameters request);
}
public class Service : IService {
//..code removed for brevity
}
然后重构您的课程,以关注GMP。这种方法称为“构造函数注入”。
public class ExampleClass {
private readonly IService service;
public ExampleClass(IService servic) {
this.service = service;
}
private void ExecuteProcess() {
var request = Transfer.RequestParameters;
service.SyncMethod(request);
}
}
在生产中,实际依赖项将在组合根中的依赖项容器中注册,并且在解析类时,将实现依赖项并将其注入到依赖类中。
这也允许在测试期间手动或使用您选择的模拟框架/工具来使用模拟/假货/存根。