您如何管理用于测试的虚拟数据?将它们与各自的实体一起保存?在单独的测试项目中?使用来自外部资源的序列化程序加载它们?或者只是在需要的地方重新创建它们?
我们有一个应用程序堆栈,其中有几个模块依赖于另一个模块,每个模块都包含实体。每个模块都有自己的测试,并且需要虚拟数据才能运行。
现在,一个具有很多依赖关系的模块将需要来自其他模块的大量虚拟数据。然而,那些不发布他们的虚拟对象,因为它们是测试资源的一部分,所以所有模块都必须一次又一次地设置他们需要的所有虚拟对象。
另外:我们实体中的大多数字段都不能为空,因此即使针对对象层运行事务也需要它们包含一些值,大多数情况下还有进一步的限制,例如唯一性、长度等。
是否有解决此问题的最佳实践方法,或者所有解决方案都会妥协?
更多详情
我们的堆栈看起来像这样:
一个模块:
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 或构造函数,这将使我们再次开始。
我们不想要的
我们不想用静态数据建立一个静态数据库,因为所需对象的结构会不断变化。现在很多,稍后。因此,我们希望 hibernate 设置所有表和列,并在单元测试时用数据填充它们。此外,静态数据库会引入许多潜在的错误和测试相互依赖性。
我的想法是否朝着正确的方向发展?处理需要大量数据的测试的最佳实践是什么?我们将有几个相互依赖的模块,这些模块需要填充来自其他几个模块的某种数据的对象。
编辑
关于我们现在如何响应第二个答案的更多信息:
因此,为简单起见,我们有三个模块:Person
、Product
、Order
。
Person
将使用MockPerson
对象测试一些管理器方法:
(在人/src/test/java :)
public class MockPerson {
public Person mockPerson(parameters...) {
return mockedPerson;
}
}
public class TestPerson() {
@Inject
private MockPerson mockPerson;
public testCreate() {
Person person = mockPerson.mockPerson(...);
// Asserts...
}
}
该类MockPerson
将不会被打包。
这同样适用于产品测试:
(在产品/src/test/java :)
public class MockProduct() { ... }
public class TestProduct {
@Inject
private MockProduct mockProduct;
// ...
}
MockProduct
需要,但不会打包。
现在 Order Tests 将需要MockPerson
and MockProduct
,所以现在我们现在需要同时创建和MockOrder
to test Order
。
(按顺序/src/test/java :)
这些是重复的,每次都需要更改Person
或Product
更改
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.MockPerson
并且order.MockPerson
无论何时Person
更改。
使用 jar 发布 Mocks 以便任何其他具有依赖关系的测试都可以调用 Mock.mock 并获得一个很好的设置对象不是更好吗?或者这是黑暗的一面——简单的方法?