简体   繁体   English

替换“密封”类的实现

[英]Replace implementation of a “sealed” class

A is a class from a referenced dll and thus cannot be changed. A是来自引用的dll的类,因此无法更改。 It has a method Foo() that is called inside my DoFoo() method (taking A as a parameter). 它有一个方法Foo() ,该方法在我的DoFoo()方法内部被调用(以A作为参数)。 I want to test DoFoo() without executing Foo() because it's expensive and already tested. 我想在不执行Foo() DoFoo()情况下测试DoFoo() ,因为它很昂贵并且已经过测试。

What's best practice to do in such a situation? 在这种情况下,最佳做法是什么?

My thoughts on this: 我对此的想法:

  • Create a wrapper class around A and pass it into DoFoo() . A周围创建包装器类,并将其传递到DoFoo() The wrapper class distinguishes between the real and the fake implementation. 包装器类区分真实的和假的实现。
  • The same could be done using extension methods. 使用扩展方法也可以做到这一点。
  • Use dynamic and pass in a fake class with an empty DoFoo() implementation. 使用dynamic并通过一个空的DoFoo()实现传递一个伪类。

Create an interface that contains the methods you want to expose. 创建一个包含要公开的方法的接口。

Create a wrapper class that implements that interface and which uses the external assembly's classes to do its work. 创建一个实现该接口并使用外部程序集的类完成其工作的包装器类。 You can create other implementations of this interface, like a mock implementation. 您可以创建此接口的其他实现,例如模拟实现。

Inject the interface with constructor injection for example, into the classes where you need the functionality. 例如,将带有构造函数注入的接口注入需要功能的类中。

In your test you can then easily replace the implementation that uses the external library with your mock implementation. 在测试中,您可以轻松地将使用外部库的实现替换为模拟实现。

Actually it's very easy doing it with Typemock , you wont need to use wrapper or create interfaces, you can just mock it. 实际上,使用Typemock做到这一点非常容易,您无需使用包装器或创建接口,只需对其进行模拟即可。 For example: 例如:

method under test: 被测方法:

public string DoFoo(A a)
    {
        string result = a.Foo();
        return result;
    }
}

sealed public class A
{
    public string Foo()
    {
        throw new NotImplementedException();
    }
}

Test: 测试:

[TestMethod,Isolated]
public void TestMethod1()
{
    var a = Isolate.Fake.Instance<A>(Members.CallOriginal);

    Isolate.WhenCalled(() => a.Foo()).WillReturn("TestWorked");

    var classUnderTest = new Class1();
    var result = classUnderTest.DoFoo(a);

    Assert.AreEqual("TestWorked", result);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM