断言实现的表达式的字符串表示形式

时间:2015-09-24 08:23:18

标签: java android assert

由于Java的assert关键字在Android上是fundamentally broken,我即将实现一个断言类,该类可以配置为检查发布版本中的断言。

现在我可以这样做:

MyAssertion.assert(a != 2)

在表达式为false时抛出AssertionException。但是,如何获取要传递给错误消息的表达式的String表示?

4 个答案:

答案 0 :(得分:5)

唯一的方法是在assert方法中添加String参数:

MyAssertion.assert(a != 2, "a must not be equal to 2");

您作为assert的输入获得的是真或假,因此您无法从中构建代表性字符串。

否则,您可以像这样实施assert

MyAssertion.assertNotEquals(a, 2);

如果失败,你知道这是因为你测试的等于2,你可以建立一个信息性的消息(虽然你不知道具体等于2)。

如果你想以某种方式能够从断言构造一个有意义的消息,我认为可能的唯一方法是构造一个String表达式,要求JavaScript引擎评估它并在表达式求值为{时构建一条消息{1}}。请注意,这会降低很多性能,因为启动JavaScript引擎需要花费大量时间。这可以通过在生产中禁用断言的机制来解决。

以下是一个例子。请注意,我正在使用新的Java 8 Nashorn JavaScript引擎,但这应该适用于较旧的Rhino。

用法示例:

false

这将引发第三个断言:

  

断言失败:3 == 4&& 'test'=='test'

这个想法是你可以编写任何可以被评估为布尔值的JavaScript友好表达式。占位符int value = 3; String str = "test"; Assertions.assertTrue("$1 == 3", value); Assertions.assertTrue("$1 == 3 && $2 == 'test'", value, str); Assertions.assertTrue("$1 == 4 && $2 == 'test'", value, str); 将替换为方法的参数($i将替换为第一个参数等)。

这是班级。它可以改进(处理错误条件,如没有足够的参数等),但这应该足以让你开始。

$1

答案 1 :(得分:4)

注释处理可以做到这一点。您可以创建一个注释,例如@InlineAssertExpressions。然后编写一个解析源文件的处理器并创建一个表示表达式的字符串,并将其添加到对assert方法的调用中,您可以重载该方法以获取可选的String参数。这种方式在性能方面是最佳的,因为内联发生在编译时。注释处理有点被忽略,但我认为这是很有用的。

答案 2 :(得分:2)

(1)使用简单,但难以实施。需要Java 8。您可以使用lambda表达式:

Assert.isTrue(() => a != 2)

在评估失败时,Assert.isTrue方法的实现应重复IDE所做的所有步骤 - (a)发现lambda类的字节码,(b)反编译例如:与JAD,(c)发现可用的来源

(2)使用简单,易于实施,但不能完全满足您的要求。您可以使用CodeStyle规则来检查&强制使用正确的断言。一个regexp将检查没有单参数断言,第二个(使用regexp back refs)将检查代码和文本描述是否相似。

(3)易于使用,易于实现,但依赖于您的构建系统。您可以在项目构建期间自动检查和修复源代码。

E.g。对于Maven构建系统,您可以创建自己的插件来检查和修复流程源阶段的源中的断言用法。

答案 3 :(得分:2)

我认为你无法访问传递给方法调用的内部java表达式。

但是,您可以使用一些表达式语言库并为断言实现执行自定义表达式处理。

以下是一些表达式语言库的列表:

http://java-source.net/open-source/expression-languages

希望有所帮助:)