【问题标题】:Extending fluent interface扩展流畅的界面
【发布时间】:2011-07-11 02:36:26
【问题描述】:

我开始使用Fluent Assertions,我非常喜欢它,但想知道是否可以像这样以一般方式扩展现有测试:

  • GroupAssert 中添加方法hasSizeAtLeast(int limit)
  • StringAssert 中添加方法startsWithIgnoringCase(String prefix)
  • 使用x.either().isIn(someSet).or().isNull()等替代方法

这些只是我可能很快需要的示例。我可以为它们中的每一个做一些解决方法,但是我失去了流畅界面的可读性和易用性。

我的最后一个例子是要抛出 iff x.isIn(someSet)x.isNull() 都做。

【问题讨论】:

  • 我会将 ... 或 ... 理解为 XOR 连接,即如果其中一个抛出,它应该抛出。 (但我不是以英语为母语的人。)
  • 我也不是,但我认为您并不完全正确。 AFAIK,当您想强调选择的存在时,也可以使用“非此即彼”。 hamcrest 也是这样使用的。
  • 流利断言的链接是 404。

标签: java fluent-interface fest


【解决方案1】:

这是作者a post 关于开放他的API 以扩展已处理类型的断言的内容。第 1 课特别讨论了取消最终确定类的更改。该帖子还给出了将StringAssert 子分类为MyStringAssert 的示例。

但是,您似乎无法以保持 API“流畅性”的方式扩展诸如 StringAssert 之类的类。 StringAssert 类不是最终的,但它仍然不允许您在子类中参数化其类型(即 StringAssert 本身中的方法返回的“this”类型)。例如,假设您在MyStringAssert 中添加了一个方法checkFoo。如您所见,以下内容无效,因为原始的 StringAssert 方法返回 StringAssert

new MyStringAssert("abcd").contains("a").checkFoo(); // compile-time error!

你只能先调用你的子类的方法,这是有效的,但有点蹩脚:

new MyStringAssert("abcd").checkFoo().contains("a"); // compiles

您可以考虑联系作者,甚至向他的 git 项目提交补丁。一种可能的解决方案是将参数化类型添加回StringAssert,并通过Assertions.assertThat(String) 中的匿名子类提供StringAssert 具体类型,无论如何这是推荐的入口点。然后,其他人都可以按照您的描述继承StringAssert。我也没有测试过这个建议,但它似乎有道理......

【讨论】:

  • 谢谢。该链接实际上显示,扩展StringAssert 并没有真正起作用,因为您无法返回MyStringAssert。所以你不能让new MyStringAssert("abcd").contains("a").hasSizeAtLeast(3);使用继承来工作。
  • 嗯,你是对的。为混乱道歉,我应该先尝试一下!我会回复以消除错误信息并提供一些建议。
  • 没问题,你帮了我很多,因为我完全不知道从哪里开始。我很确定你的建议是有道理的。很遗憾,Java 只为self-types 提供了如此糟糕的解决方法,迫使每个人要么用其他无用的泛型参数污染代码,要么失去灵活性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-19
  • 1970-01-01
  • 2010-09-29
  • 2022-08-19
  • 2014-09-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多