Unit testing tdd-为第三方代码创建测试

Unit testing tdd-为第三方代码创建测试,unit-testing,testing,tdd,functional-testing,functional-dependencies,Unit Testing,Testing,Tdd,Functional Testing,Functional Dependencies,如果我测试的方法或过程依赖于第三方的代码,我如何创建单元测试?比如说,我有一个方法,它使用来自第三方源的类,而这些类需要只在功能测试中完成的设置。我应该如何处理这个问题?大多数时候,第三方依赖不能被嘲笑,但我的方法确实需要利用它 此外,我是否应该避免使用实际数据进行单元测试甚至功能测试?比如,我的测试是否应该永远不要连接到数据库API来临时添加数据、对其进行操作和测试,然后再将其删除?通常,假设第三方软件经过测试,并且工作正常。尽管当你发现一个bug时会让你感到惊讶 这取决于单元测试的内容。有些

如果我测试的方法或过程依赖于第三方的代码,我如何创建单元测试?比如说,我有一个方法,它使用来自第三方源的类,而这些类需要只在功能测试中完成的设置。我应该如何处理这个问题?大多数时候,第三方依赖不能被嘲笑,但我的方法确实需要利用它


此外,我是否应该避免使用实际数据进行单元测试甚至功能测试?比如,我的测试是否应该永远不要连接到数据库API来临时添加数据、对其进行操作和测试,然后再将其删除?

通常,假设第三方软件经过测试,并且工作正常。尽管当你发现一个bug时会让你感到惊讶

这取决于单元测试的内容。有些事情,比如访问一些外来的硬件或资源,或者简单的网络连接,不应该进行单元测试。对于此类调用,我们使用mock,而不进行单元测试


对于数据库,您可以使用mock而不是真实类来访问数据库。或者,您可以使用单元测试设置方法在内存中创建数据库,并在清理中销毁它们。

单元测试

你应该测试一切。但并不是所有的东西都使用单元测试。单元测试不依赖于环境-数据库、internet连接等。使用不受信任/不稳定的第三方工具的最佳实践是在代码和第三方代码之间创建反损坏层。因此,重构代码,使业务逻辑尽可能独立。并对业务逻辑进行单元测试

如果您不确定第三方代码是如何工作的,或者将来是否会更改,您可以进行“学习测试”。这些是单元测试(如果可能的话),可以断言您所依赖的行为。在学习测试中,您只测试第三方代码,而不是您的代码

如果第三方代码更不可信(众所周知的开源库),那么您假设它可以工作,不做任何分离,您只对代码进行单元测试,而不是库

非单元测试

如果您的测试需要外部环境(数据库、网络等),那么您应该进行集成测试。它的目的不是测试业务逻辑,而是测试是否正确连接了所有部分。sql测试是最著名的例外之一

如何进行集成测试没有简单的规则(您可以编写有关sql测试的书籍)。这取决于您想要测试的内容,以及您需要/想要的生产环境的相似性。例如,您可以针对内存中的数据库或生产数据库(如oracle、postgres等)进行sql测试。无论您如何设计集成测试,都必须确保每个测试都从了解环境状态开始。并且考虑到环境中的错误,这些环境的污染和测试速度

< P>:你说:

大多数情况下,第三方依赖关系不能被嘲笑

为什么??您可以始终为与第三方组件的交互定义一个接口,然后提供一个实现,该实现只需将每个调用委托给第三方组件,然后您就可以为测试提供该接口的模拟

如果第三方组件有一个大的API,这可能需要做很多工作,但仍然值得一做

在.net文件系统类周围创建包装器也存在类似的情况,以便您可以编写不依赖文件系统的测试

所以你可以这样做:

public interface IMyDependency
{
    public void SomeMethod();

    public int CaclateSomething();

    //add other methods that you will call in the 3rd party dependency
}
public class MyDependencyWrapper : IMyDependency
{
    private My3rdPartyDepency actualDependency;

    public MyDependencyWrapper(My3rdPartyDepency actualDependency)
    {
         this.actualDependency=actualDependency;
    }

    public void SomeMethod()
    {
        actualDependency.SomeMethod()l
    }

    public int CaclateSomething(string aParam)
    {
        return actualDependency.CalculateSomething(aParam);
    }

    //add other methods that you will call in the 3rd party dependency
}
然后有一个包装器,它只代表您正在使用的实际第三方组件,如下所示:

public interface IMyDependency
{
    public void SomeMethod();

    public int CaclateSomething();

    //add other methods that you will call in the 3rd party dependency
}
public class MyDependencyWrapper : IMyDependency
{
    private My3rdPartyDepency actualDependency;

    public MyDependencyWrapper(My3rdPartyDepency actualDependency)
    {
         this.actualDependency=actualDependency;
    }

    public void SomeMethod()
    {
        actualDependency.SomeMethod()l
    }

    public int CaclateSomething(string aParam)
    {
        return actualDependency.CalculateSomething(aParam);
    }

    //add other methods that you will call in the 3rd party dependency
}

现在,您可以在测试中只使用接口,这样就可以编写单元测试,而不依赖于实际的第三方组件。

感谢您提到反损坏层。现在我明白我在寻找什么了。但是,这些接口实现中的所有方法/过程都可以进行单元测试吗?还是我应该在功能测试上担心这个问题?谢谢你的回答。还有一个与此相关的好问题