【问题标题】:How to unit-test third-party library wrappers?如何对第三方库包装器进行单元测试?
【发布时间】:2016-04-25 22:34:05
【问题描述】:

每个人都告诉不要嘲笑你不拥有的东西。他们建议改为为 3rd 方库制作包装器。

但是我该如何测试这个包装器呢?

我的意思是,如果我为它编写单元测试并模拟那些 3rd 方接口来测试我的包装器,那么什么都不会改变。 如果库维护者将更改其 API,我将面临同样的问题 - 模拟库的测试将正常,软件将在生产环境中失败。 这里的可靠性或可测试性有什么优势?

我知道代码质量有优势,因为我可以随时更换这个库,但这不是这个问题的主题。

谢谢。

【问题讨论】:

    标签: unit-testing


    【解决方案1】:

    对您的 3rd 方库的抽象进行单元测试,以确保您的代码按预期运行,然后对 3rd 方库进行集成测试,以确保这些集成的行为符合预期。如果那些 3rd 方库有沙盒可以安全地测试,那就更好了。

    例如,如果您正在测试的系统依赖于第 3 方库,但您希望在不调用实际库的情况下对其进行单元测试。您可以手动或使用模拟框架提供第 3 方接口的 Mock 实现。

    public interface IExteralContract {
        List<string> DoSomething(params string[] args);
    }
    
    [TestMethod]
    public void SUT_Should_Be_True {
        //Arrange
        IExteralContract mock = new MockExternalContract();
        var sut = new MyClass(mock);
        //Act
        var actual = sut.DoSomethingElse();
        //Assert
        Assert.IsTrue(actual);
    }
    

    在这种情况下,被测系统是依赖于第 3 方接口的类之一。

    对于您的集成测试,被测系统是实际的第 3 方包装器,以确保其行为符合预期。

    public class ConcreteExternalWrapper : IExteralContract {
       public List<string> DoSomething(params string[] args){
           //Actual calling of 3rd party libraries
       }
    }
    
    [TestMethod]
    public void Third_Party_Service_Should_Return_Data {
        //Arrange
        IExteralContract sut = new ConcreteExternalWrapper ();
        int expected = 3;
        //Act
        var actual = sut.DoSomething("arg1", "arg2", "arg3");
        //Assert
        Assert.IsNotNull(actual);
        Assert.AreEqual(expected, actual.Count);
    }
    

    这样,如果库维护者更改其 API,行为将导致预期行为失败。

    希望这能满足您的要求。

    【讨论】:

    • 这是否意味着我不应该为我的包装器编写这样的单元测试并稍后在整个环境中对其进行测试?
    • 我想说仍然按照 TDD 方法编写单元测试,并在需要使用环境进行测试时进行集成测试。
    • @Elessar.perm 用一个例子更新了我的答案。看看它是否清除了任何东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 2017-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多