Nat*_*len 2 java whitespace unit-testing hamcrest matcher
因此,当我们需要将一些 HTML 解析为 XML 并验证 HTML 中的所有内容都在 XML 文件中时,我们使用 Unittests 中的 Hamcrest 进行验证。由于我们不能在 XML 文件中包含更多或更少的信息,因此我们有一个不使用contains而是使用 的匹配器很重要equalTo。问题是我们解析但必须提取某些元素,因为它们在外部管理的数据模型中是不允许的。我们发现这样做在某些情况下会增加额外的空格(与 Jsoup 有关系)。
因此,由于空间与实际内容无关,我们决定暂时忽略它们(因为这纯粹是 PoC),但我们确实希望验证我们的概念。为此,我想出了一个解决方案,它去除每个空格 ( String.replaceAll("\\s","")),同时去除换行符和制表符。然后将所有文本连接成一个 String 对象,这使得阅读非常糟糕,而且在调试时也不是一个很好的做法。所以我选择使用 Hamcrests IsEqualIgnoringWhitespace. 在测试时,我发现它根本没有像名字所暗示的那样做任何事情。在代码中没有删除空格、制表符或换行符,而是检查当前字符是否为空格,如果是,则之前的字符是否也包含空格。如果是这种情况,它将删除一个空格。因此,基本上它只会将空格标准化为在两个单词之间仅包含其中一个。
下面是stripSpace类中使用的方法的代码:
public String stripSpace(String toBeStripped) {
final StringBuilder result = new StringBuilder();
boolean lastWasSpace = true;
for (int i = 0; i < toBeStripped.length(); i++) {
char c = toBeStripped.charAt(i);
if (isWhitespace(c)) {
if (!lastWasSpace) {
result.append(' ');
}
lastWasSpace = true;
} else {
result.append(c);
lastWasSpace = false;
}
}
return result.toString().trim();
}
Run Code Online (Sandbox Code Playgroud)
所以本质上它根本不会忽略空格。那为什么叫这个名字呢?
给出一些我们想要相互匹配的输入示例,这里是一些有空格但不应该的文本(文本是荷兰语,但这并不重要):
m2与m 2(HTML原:m<sup>2</sup>)
Tabel 3.1与Tabel 3 .1(HTML原:Tabel <a href="link to table">3</a>.1)
因此,由于这些文本永远不会被普通equalTo匹配器匹配,equalToIgnoringWhitespaces因此实际上应该根据名称匹配它,但事实并非如此。
你们中有人知道是否真的有一个实际上忽略空格的匹配器吗?
根据 Javadocs IsEqualIgnoringWhitespace:
创建一个字符串匹配器,当检查的字符串等于指定的 expectedString 时匹配,当空白差异(大部分)被忽略时。
这在MatchersJavadocs中有更详细的解释:
创建一个字符串匹配器,当检查的字符串等于指定的 expectedString 时匹配,当空白差异(大部分)被忽略时。确切地说,应用了以下空白规则:
- 忽略预期字符串和检查字符串的所有前导和尾随空格
- 任何剩余的空白,即字符串中出现,已折叠到一个单一的空间比较之前
以下测试验证此行为:
@Test
public void testIsEqualIgnoringWhitespace() {
// leading and trailing spaces are ignored
assertThat("m 2", equalToIgnoringWhiteSpace(" m 2 "));
// all other spaces are collapsed to a single space
assertThat("m 2", equalToIgnoringWhiteSpace("m 2"));
// does not match because the single space in the expected string is not collapsed any further
assertThat("m2", not(equalToIgnoringWhiteSpace("m 2")));
}
Run Code Online (Sandbox Code Playgroud)
所以,这就解释了为什么您会看到您在问题中描述的行为。
回复这个:
你们中有人知道是否真的有一个实际上忽略空格的匹配器吗?
您可以编写自己的匹配器。下面是一个例子:
public class IgnoresAllWhitespacesMatcher extends BaseMatcher<String> {
public String expected;
public static IgnoresAllWhitespacesMatcher ignoresAllWhitespaces(String expected) {
return new IgnoresAllWhitespacesMatcher(expected);
}
private IgnoresAllWhitespacesMatcher(String expected) {
this.expected = expected.replaceAll("\\s+", "");
}
@Override
public boolean matches(Object actual) {
return expected.equals(actual);
}
@Override
public void describeTo(Description description) {
description.appendText(String.format("the given String should match '%s' without whitespaces", expected));
}
}
Run Code Online (Sandbox Code Playgroud)
使用这个匹配器可以通过以下测试:
@Test
public void testUsingCustomIgnoringAllWhitespaceMatcher() {
// leading and trailing spaces are ignored
assertThat("m2", ignoresAllWhitespaces(" m 2 "));
// intermediate spaces are ignored
assertThat("m2", ignoresAllWhitespaces("m 2"));
}
Run Code Online (Sandbox Code Playgroud)