协议。如何在 URL 中使用自动生成的 ID 测试 REST GET

Pact. How to test a REST GET with automatically generated ID in the URL

我想测试一个 REST 服务,该服务 returns 由 UUID 标识的给定实体的详细信息,即我的消费者协议有一个请求 GET 的交互,如下所示:

/cities/123e4567-e89b-12d3-a456-426655440000

所以我需要这个特定的记录存在于数据库中,以便契约验证者找到它。在其他项目中,我已经实现了在状态设置中执行 SQL INSERT,但在这种情况下,我更愿意使用微服务的 JPA 实用程序来访问数据库,因为数据模型非常复杂并且使用这些实用程序会节省我很多精力并使测试更易于维护。

问题是这些实用程序不允许在您创建新记录时指定标识符(它们会分配一个自动 ID)。所以在创建实体之后(在状态设置中)我想告诉契约验证者使用生成的 ID 而不是消费者契约指定的 ID。

据我所知,Pact 匹配技术在这里没有用,因为我需要微服务来接收这个特定的 ID。验证者有什么方法可以知道在调用服务时使用的正确 ID?

不幸的是没有。提供方验证者从协议文件本身获取此信息,因此不知道如何发送其他任何信息。

最好的选择是使用 provider states 来管理此测试用例之前特定记录的注入(或者首先将正确的记录放入其中)。

您在提供程序状态设置期间使用 JPA 库将记录中的 UUID 修改为您期望的内容。

如果您在消费者端和提供者端都使用 pact-jvm,我相信您可以使用 'generators',但您需要查阅相关文档,因为我没有'我没用过。

这里有两个选择:

选项 1 - 找到一种使用协议文件中的 UUID 的方法

这个选项(在我的选项中)会更好,因为您使用众所周知的值进行验证。使用 JPA,我认为您可以禁用 ID 的自动生成。如果您使用 Hibernate 作为 JPA 提供者,如果您提供了一个 ID,它可能不会生成一个 ID(即将实体上的 ID 设置为保存之前来自契约文件的 ID)。这是我最近做的。

使用生成器(如 Beth 所提到的)将是解决此问题的一个很好的机制,但目前没有提供生成器来使用特定值的方法。他们即时生成随机的。

选项 2 - 替换 URL 中的 ID

根据您 运行 验证的方式,您可以使用请求过滤器将 URL 中的 UUID 更改为在提供程序状态回调期间创建的 UUID。但是,我认为这可能是一件坏事,因为您可能会以削弱合同的方式更改请求。您将不会验证您的提供商是否遵守消费者指定的内容。

如果选择此选项,请注意只更改 URL 的 UUID 部分,不要更改其他任何内容。

有关请求过滤器的信息,请查看 Pact-JVM 自述文件中的 Gradle - Modifying the requests before they are sent and JUnit - Modifying the requests before they are sent