gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:58:45 25 4
gpt4 key购买 nike

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

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

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

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

是否有最佳实践方式解决这个问题,或者所有解决方案都妥协了?

更多详情

我们的堆栈看起来像这样:

一模块:

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)

    A 测试模块 电话 可以保存所有虚拟对象并在测试范围内将它们提供给所有模块中的所有测试(因此加载的依赖项不会受到干扰)。那行得通吗?含义:如果我加载 电话 一个 并在 上运行安装一个 它将不包含由 引入的引用吗?电话 尤其不是 ?然而 一个 会知道 的数据模型。

    选项 b)

    模块 A 在 src/main/java../entities/dummy 中的某处提供了虚拟对象。允许 获取它们同时 一个 不知道 的虚拟数据

    选项 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需要但不会打包。

    现在订单测试将需要 MockPersonMockProduct ,所以现在我们现在需要同时创建 MockOrder测试 Order .

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

    这些是重复的 并且每次都需要更改 PersonProduct变化
    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.MockPersonorder.MockPerson每当 Person被改变。

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

    最佳答案

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

    我通常所做的(Java 中的 AFAIKT 是最佳实践)是尝试使用测试数据构建器模式,如 Nat Pryce 所述。在他的 Test Data Builders邮政。

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

  • Does a framework like Factory Girl exist for Java?
  • make-it-easy , Nat 的框架实现了这种模式。
  • 关于java - 模块化应用程序堆栈中的虚拟数据和单元测试策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8836338/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com