伪造在构造函数中创建的数据成员

时间:2017-08-24 09:55:09

标签: c# unit-testing mocking

我有以下课程:

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)的调用。 有谁知道我怎么能这样做?

4 个答案:

答案 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);
    }
}

在生产中,实际依赖项将在组合根中的依赖项容器中注册,并且在解析类时,将实现依赖项并将其注入到依赖类中。

这也允许在测试期间手动或使用您选择的模拟框架/工具来使用模拟/假货/存根。