Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 单元测试需要很多接口?_Java_C++_Unit Testing_Googletest_Googlemock - Fatal编程技术网

Java 单元测试需要很多接口?

Java 单元测试需要很多接口?,java,c++,unit-testing,googletest,googlemock,Java,C++,Unit Testing,Googletest,Googlemock,我目前正在做我的第一个使用TDD和单元测试的项目。我在C++中用 GoGoLeestEng/和 GoGoReMoCu库。该项目需要许多具有特定功能的小型类。我主要在构造函数中使用依赖项注入。据此: 及 注入到构造函数中的依赖项是单元测试中模拟的良好候选项。在C++中有两种方法可以做到这一点: 创建接口(纯虚拟类)。生产类和模拟类就是从中派生出来的 在生产类内创建虚拟成员函数。Mock类派生自生产类。当生产类未定义默认构造函数时会出现问题。模拟类必须显式地调用基类构造函数(就个人而言,这不是模拟

我目前正在做我的第一个使用TDD和单元测试的项目。我在C++中用<强> GoGoLeestEng/<强>和<强> GoGoReMoCu库。该项目需要许多具有特定功能的小型类。我主要在构造函数中使用依赖项注入。据此:

注入到构造函数中的依赖项是单元测试中模拟的良好候选项。在C++中有两种方法可以做到这一点:

  • 创建接口(纯虚拟类)。生产类和模拟类就是从中派生出来的
  • 在生产类内创建虚拟成员函数。Mock类派生自生产类。当生产类未定义默认构造函数时会出现问题。模拟类必须显式地调用基类构造函数(就个人而言,这不是模拟对象应该做的事情)

  • 你如何处理这种情况?您喜欢多个接口(N个类需要N个接口)还是从基类派生?

    对于这样的问题,没有单一的最佳答案,但我可以分享我的团队的一些经验。我们使用的方法如下。这个项目被分成我们内部称为“模块”的部分。这些基本上只是C++类,但它们的特殊之处在于,它们是项目中最大的/最重要的类。这些类的接口向其他模块公开(这是通过CMake配置的),因此它们可以相互使用。每个模块都是一个小的静态库,在该库中还有另外的C++类,它们只需要完成包含模块的功能,而与其他模块无关。这些被配置为模块专用(同样通过CMake),其他模块不知道这些类

    在简要说明了我们的项目是如何组织的之后,回到您的问题:

  • 对于需要向其他模块公开的模块的主要类(通常为1-3),我们创建了一个带有详细文档的接口(纯虚拟类)(详细说明客户机应如何使用类的精确合同、序列图、所有方法的详细文档等)。然后我们有一个从这个接口继承的mock,它向其他模块公开,还有一个实现类(您称之为生产类),它也继承了这个模块,但它是模块的私有类(其他类不需要实现细节,只需要知道如何创建和使用接口实例)

  • 对于每个模块中的其他私有类,我们只需在生产类中创建虚拟方法,以使事情更简单,而它们的模拟只是从生产类继承。顺便说一下,通过在生产类中声明一个受保护的默认构造函数,您的默认构造函数问题应该很容易得到解决


  • 在我看来,这在避免太多样板代码(通过为每个类提供一个接口)和为项目中最重要的类提供漂亮、干净和精确定义的接口之间提供了一个很好的平衡。

    对于这样的问题,没有唯一的最佳答案,但我可以分享我的团队的一些经验。我们使用的方法如下。这个项目被分成我们内部称为“模块”的部分。这些基本上只是C++类,但它们的特殊之处在于,它们是项目中最大的/最重要的类。这些类的接口向其他模块公开(这是通过CMake配置的),因此它们可以相互使用。每个模块都是一个小的静态库,在该库中还有另外的C++类,它们只需要完成包含模块的功能,而与其他模块无关。这些被配置为模块专用(同样通过CMake),其他模块不知道这些类

    在简要说明了我们的项目是如何组织的之后,回到您的问题:

  • 对于需要向其他模块公开的模块的主要类(通常为1-3),我们创建了一个带有详细文档的接口(纯虚拟类)(详细说明客户机应如何使用类的精确合同、序列图、所有方法的详细文档等)。然后我们有一个从这个接口继承的mock,它向其他模块公开,还有一个实现类(您称之为生产类),它也继承了这个模块,但它是模块的私有类(其他类不需要实现细节,只需要知道如何创建和使用接口实例)

  • 对于每个模块中的其他私有类,我们只需在生产类中创建虚拟方法,以使事情更简单,而它们的模拟只是从生产类继承。顺便说一下,通过在生产类中声明一个受保护的默认构造函数,您的默认构造函数问题应该很容易得到解决


  • 在我看来,这在避免太多样板代码(通过为每个类提供一个接口)和为项目中最重要的类提供漂亮、干净和精确定义的接口之间提供了很好的平衡。

    为什么要标记Java?对于我的两分钱,在java中使用
    Mockito.mock()
    可以通过使用cglib代理直接模拟
    ,但我不确定这在c++中是如何工作的,为什么要标记java?对于我的两分钱,在java中使用
    Mockito.mock()
    您可以通过使用cglib代理直接模拟
    ,但我不确定这在c++中是如何工作的,谢谢!你的方法很合适。您说过基类中的受保护构造函数将解决这些问题。是的,但是考虑到生产没有默认的公共构造函数和受保护的默认编译器必须初始化Prima。