Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.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_Unit Testing_Testing_Maven_Modular - Fatal编程技术网

Java 模块化应用程序堆栈中的虚拟数据和单元测试策略

Java 模块化应用程序堆栈中的虚拟数据和单元测试策略,java,unit-testing,testing,maven,modular,Java,Unit Testing,Testing,Maven,Modular,如何管理用于测试的虚拟数据?将它们保存在各自的实体中?在单独的测试项目中?从外部资源用序列化程序加载它们?或者只是在需要的地方重新创建它们 我们有一个包含多个模块的应用程序堆栈,每个模块依赖于另一个模块,每个模块都包含实体。每个模块都有自己的测试,需要虚拟数据来运行 现在,一个具有大量依赖项的模块将需要来自其他模块的大量虚拟数据。但是,这些模块不会发布它们的虚拟对象,因为它们是测试资源的一部分,所以所有模块都必须一次又一次地设置它们需要的所有虚拟对象 另外:我们实体中的大多数字段都不可为空,因此

如何管理用于测试的虚拟数据?将它们保存在各自的实体中?在单独的测试项目中?从外部资源用序列化程序加载它们?或者只是在需要的地方重新创建它们

我们有一个包含多个模块的应用程序堆栈,每个模块依赖于另一个模块,每个模块都包含实体。每个模块都有自己的测试,需要虚拟数据来运行

现在,一个具有大量依赖项的模块将需要来自其他模块的大量虚拟数据。但是,这些模块不会发布它们的虚拟对象,因为它们是测试资源的一部分,所以所有模块都必须一次又一次地设置它们需要的所有虚拟对象

另外:我们实体中的大多数字段都不可为空,因此即使在对象层上运行事务也需要它们包含一些值,大多数情况下还存在其他限制,如唯一性、长度等

是否有一种最佳实践方法可以解决这个问题,或者所有解决方案都是折衷方案


更多细节

我们的堆栈如下所示:

一个模块:

src/main/java --> gets jared (.../entities/*.java contains the entities)
src/main/resources --> gets jared
src/test/java --> contains dummy object setup, will NOT get jared
src/test/resources --> not jared
我们使用Maven来处理依赖关系

模块示例:

  • 模块A有一些虚拟对象
  • 模块B需要自己的对象,与模块A相同
选项a)

测试模块T可以保存所有虚拟对象,并在测试范围内将它们提供给所有模块中的所有测试(因此加载的依赖项不会受到影响)。这样行吗?意思:如果我在A中加载T并在A上运行install,它将不包含T引入的引用,尤其是不包含B?然而,A将了解B的数据模型

选项b)

模块A在
src/main/java../entities/dummy
中的某处提供虚拟对象,允许B获取它们,而A不知道B的虚拟数据

选项c)

每个模块都包含作为序列化虚拟对象的外部资源。它们可以由需要它们的测试环境反序列化,因为它依赖于它们所属的模块。这将要求每个模块创建并序列化它的虚拟对象,而我们将如何做到这一点?如果使用另一个单元测试,它会在单元测试之间引入不应该发生的依赖关系,或者使用脚本,那么调试将很困难,也不灵活

选项d)

使用模拟框架,并根据需要为每个测试手动分配所需字段。这里的问题是,实体中的大多数字段都不可为空,因此需要调用setter或constructor,这将导致我们再次开始

我们不想要的

我们不想用静态数据建立静态数据库,因为所需对象的结构将不断变化。现在很多,晚一点。因此,我们希望hibernate设置所有表和列,并在单元测试时用数据填充这些表和列。此外,静态数据库会引入许多潜在错误和测试相关性


我的想法正确吗?处理需要大量数据的测试的最佳实践是什么?我们将有几个相互依赖的模块,这些模块需要对象填充来自其他几个模块的某种数据


编辑

关于第二个答案,我们现在如何做的更多信息:

为了简单起见,我们有三个模块:
产品
订单
Person
将使用
MockPerson
对象测试一些管理器方法:

(亲自/src/test/java:)

不会打包
MockPerson

同样适用于产品测试:

(在product/src/test/java:)

MockProduct
是必需的,但不会打包

现在,订单测试将需要
MockPerson
MockProduct
,因此现在我们需要创建这两个组件以及
MockOrder
来测试
订单

(顺序为/src/test/java:)

这些是重复的,需要在每次
人员
产品
更改时进行更改

public class MockProduct() { ... }
public class MockPerson() { ... }
这是唯一应该在这里的类:

public class MockOrder() { ... }

public class TestOrder() {
    @Inject
    private order.MockPerson mockPerson;
    @Inject
    private order.MockProduct mockProduct;
    @Inject
    private order.MockOrder mockOrder;
    public testCreate() {

        Order order = mockOrder.mockOrder(mockPerson.mockPerson(), mockProduct.mockProduct());
        // Asserts...
    }
}
问题是,现在我们必须在
person
发生更改时更新
person.MockPerson
order.MockPerson


用jar发布Mock不是更好吗?这样其他所有具有依赖关系的测试都可以调用Mock.Mock并获得一个很好的设置对象?或者这是黑暗的一面-简单的方法?

这可能适用,也可能不适用-我很想看看您的虚拟对象和相关设置代码的示例。(为了更好地了解它是否适用于您的情况。)但我过去所做的工作甚至没有在测试中引入此类代码。正如您所描述的,它很难生成、调试,尤其是打包和维护

我所做的(Java中的AFAIKT是最佳实践)是尝试使用TestDataBuilder模式,正如在他的文章中所描述的

如果您认为这有点相关,请查看以下内容:

  • ,实现此模式的Nat框架

我想知道您是否无法通过改变测试方法来解决问题

单元测试依赖于其他模块的模块,因此,依赖于其他模块的测试数据的模块不是真正的单元测试

如果您要为被测模块的所有依赖项注入一个mock,这样您就可以完全隔离地测试它了。然后,您不需要设置一个完整的环境
public class MockProduct() { ... }
public class MockPerson() { ... }
public class MockOrder() { ... }

public class TestOrder() {
    @Inject
    private order.MockPerson mockPerson;
    @Inject
    private order.MockProduct mockProduct;
    @Inject
    private order.MockOrder mockOrder;
    public testCreate() {

        Order order = mockOrder.mockOrder(mockPerson.mockPerson(), mockProduct.mockProduct());
        // Asserts...
    }
}