【发布时间】:2014-08-16 21:21:35
【问题描述】:
我正在尝试在 spock 或 hamcrest 中编写与域相关的自定义断言/匹配器,但我不确定如何继续。
我尝试在 hamcrest 中编写自定义 Matcher,但到目前为止,这只是部分解决方案。
我正在寻找有关在这种情况下的正确路线的指导。
领域对象:
- ResultMap 有一个对象 Map - 有一个 INodeResult 与每个 ILine 关联。
- IResult 有 4 个 (Google Guava) 多图对象需要验证。
我想在我的 spock 测试中做的事情是这样的:
expect:
that actualResultMap, matchesInAnyOrder(expectedResultMap)
or
that actualResultMap, matches(expectedResultMap) // Will only match if everything is in the same order.
内部代码将评估每个条目并对内部对象进行适当的测试。
到目前为止,我设法编写了评估一组多图的部分代码,但我不确定如何链接我的测试。
自定义匹配器:
package com.ps.DE.Test.CustomMatcher
import org.hamcrest.BaseMatcher
class MultimapMatcher {
/**
* Checks all the entries in a Multimap with another
* @param expected
* @return Shows the failure only if the entries do not match or are not in the same order
*/
static hasAllInOrder(final com.google.common.collect.Multimap expected){
[
matches: { actual ->
for(key in actual.keySet()){
if (actual.get(key) != expected.get(key)){
return false
}
}
return true
},
describeTo: { description ->
description.appendText("MultiMap entries to be ${expected}")
},
describeMismatch: { actual, description ->
description.appendText("were ${actual}")
}
] as BaseMatcher
}
/**
* Checks all the entries in a Multimap with another
* @param expected
* @return Shows the failure only if the entries do not match
*/
static hasAllInAnyOrder(final com.google.common.collect.Multimap expected){
[
matches: { actual ->
for(key in actual.keySet()){
if (!actual.get(key).containsAll(expected.get(key))) {
return false
}
}
return true
},
describeTo: { description ->
description.appendText("MultiMap entries to be ${expected}")
},
describeMismatch: { actual, description ->
description.appendText("were ${actual}")
}
] as BaseMatcher
}
}
测试自定义匹配器:
package com.ps.DE.Test.CustomMatcher
import com.google.common.collect.ArrayListMultimap
import com.google.common.collect.Multimap
import spock.lang.Specification
import static com.ps.DE.Test.CustomMatcher.MultimapMatcher.hasAllInAnyOrder
import static com.ps.DE.Test.CustomMatcher.MultimapMatcher.hasAllInOrder
import static org.hamcrest.Matchers.not
import static spock.util.matcher.HamcrestSupport.that
class MultimapMatcherSpec extends Specification {
def "Test hasAllInOrder"() {
def actual = ArrayListMultimap.create();
// Adding some key/value
actual.put "Fruits", "Apple"
actual.put "Fruits", "Banana"
actual.put "Fruits", "Pear"
actual.put "Vegetables", "Carrot"
Multimap<String, String> expected = ArrayListMultimap.create();
// Adding some key/value
expected.put("Fruits", "Apple");
expected.put("Fruits", "Banana");
expected.put("Fruits", "Pear");
expected.put("Vegetables", "Carrot");
expect:
that actual, hasAllInAnyOrder(expected)
that actual, hasAllInOrder(expected)
}
def "Test hasAllInAnyOrder"() {
Multimap<String, String> actual = ArrayListMultimap.create();
// Adding some key/value
actual.put("Fruits", "Apple");
actual.put("Fruits", "Banana");
actual.put("Fruits", "Pear");
actual.put("Vegetables", "Carrot");
Multimap<String, String> expected = ArrayListMultimap.create();
// Adding some key/value
expected.put("Fruits", "Banana");
expected.put("Fruits", "Apple");
expected.put("Fruits", "Pear");
expected.put("Vegetables", "Carrot");
expect:
that actual, hasAllInAnyOrder(expected)
that actual, not(hasAllInOrder(expected))
}
}
我们将不胜感激任何帮助或指导。
【问题讨论】:
-
你卡在哪里了?您当前的匹配器是否有效?建议:接受匹配器工厂方法以在内部创建匹配器以应用于条目对。这将使整个 MultiMap 匹配器更加通用,并允许重复使用现有的列表匹配器,而无需创建新的子类。
-
@DavidHarkness 感谢您的建议。你能给我举个例子来正确地做到这一点吗?
-
我想看看
CoreMatchers类的 Hamcrest 源代码。很有启发性。
标签: java unit-testing groovy spock hamcrest