我目前正在研究 Pact,作为测试策略开发的一部分。它是一个微服务架构,并且有各种服务器到服务器的连接,我可以看到它非常有用(包括消息队列)。
然而,我无法准确理解它应该如何工作的一个地方是客户端和服务器之间的连接。在我们最常见的模式中,我们有一个 Java 微服务,充当 Typescript/Angular Web 客户端的服务器。服务器采用OpenAPI规范;具体来说,我们手动编写 OpenAPI 规范文件,然后从规范文件生成服务器和客户端代码 - 服务器代码是我们期望实现的控制器的一系列接口,客户端代码是服务和模型库客户端可以使用它向服务器发出请求。客户端上的这种模式使 HTTP 请求变得轻而易举,原因如下:
一方面,在此设置中使用 Pact 绝对可以带来一些好处:
另一方面,我也有一些担忧:
坦率地说,仅第一个积极因素就足以让我承诺加入 Pact。消费者驱动的方法使得生成存根的过程变得更加有意义。话虽这么说,负面影响肯定会让我感到厌烦。感觉工作量很大,其中大部分是引入冗余验证机制,这样我们就可以获取单一利益。
我这样做是错误的吗?我是否可以对这种方法进行简单的改变,以获得相同的好处而不引入冗余?或者我只需要接受这就是方式?
编辑:所以我开始研究使用契约生成存根服务器的工具,结果发现它非常缺乏。内置的 pact 服务器存根不支持以编程方式向正在运行的服务器添加模拟,而且我发现将 pact 转换为与其他服务器存根库一起使用的大多数库都非常小,并且维护得不是特别好。这意味着我们可能必须为存根过程构建我们自己的解决方案,这使得 Pact 的吸引力更小=/
所以我有一个嵌套模型结构,看起来像这样:
public class TagArea {
private List<TagGroup> groups;
... constructors, getters, setters, etc.
}
public class TagGroup {
private String tagName;
private List<TagGroup> subgroups;
... constructors, getters, setters, etc.
}
Run Code Online (Sandbox Code Playgroud)
以及返回所述模型的控制器。但是,生成的 swagger.json 的架构部分如下所示:
{ "components":
{ "schemas": {
"TaxonomyClientMetadata": {
"type": "object", "properties": {
"tagGroups": {"type": "array", "items": {"$ref": "#/components/schemas/TagGroup"}}
}
},
"TagGroup": {
"type": "object", "properties": {
"tagName": {"type": "string"}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
整个财产就这样……消失了。我希望该TagGroup对象看起来更像这样:
"TagGroup": {
"type": "object", "properties": {
"tagName": {"type": "string"},
"subgroups": {"type": "array", …Run Code Online (Sandbox Code Playgroud) 我会尽量保持这个简短.我正在尝试做这样的事情:
public enum Fruit {
APPLE("Apple", appleHelper::doAppleThing),
ORANGE("Orange", orangeHelper::doOrangeThing);
private String name;
private Function<String, List<T>> fruitFunction;
Fruit(String name, Function<String, List<T>> fruitFunction) {
this.name = name;
this.fruitFunction = fruitFunction;
}
public String getName() {
return name;
}
public <T> List<T> applyFruitFunction(String someString) {
return fruitFunction.apply(someString);
}
}
Run Code Online (Sandbox Code Playgroud)
这样以后,我可以有一个像这样的方法
private <T> List<T> doFruitThing(String someString, Fruit fruit) {
List<T> transformedFruits = fruit.applyFruitFunction(someString);
if (transformedFruits.isEmpty()) {
throw new FruitException("There was no fruit of type " + fruit.getName());
}
return transformedFruits;
}
Run Code Online (Sandbox Code Playgroud)
我遇到了两个问题.
doAppleThing而 …