我正在尝试在spock或hamcrest中编写与自定义域相关的断言/匹配器,但我不确定如何继续。
我尝试在hamcrest中编写自定义匹配器,但到目前为止只能让我得到部分解决方案。
我正在寻找关于这种情况下适当课程的一些指导。
域对象:
我在spock测试中想要做的是:
expect:
that actualResultMap, matchesInAnyOrder(expectedResultMap)
or
that actualResultMap, matches(expectedResultMap) // Will only match if everything is in the same order.
然后内部代码将评估每个条目,并对内部对象进行适当的测试。
到目前为止,我设法编写了一部分代码来评估一组multimap,但我不确定如何将我的测试链接起来。
自定义匹配器:
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))
}
}
非常感谢任何帮助或指导。
答案 0 :(得分:0)
为什么你需要自定义匹配器?也许,Spock和Groovy足以满足您的需求而无需自定义匹配器。
要匹配两个Multimap
个对象,它们具有相同的内容,它们就足够了:
expected:
actual == expected
在相同的断言中添加更多代码有什么好处吗?
对于任何顺序的匹配,它有点棘手,但它足以添加排序方法(可以在其他测试类中提取和重用)。这看起来像是:
expected:
sortValues(actual) == sortValues(expected)
和方法本身:
static Map<String, Collection<String>> sortValues(Multimap<String, String> multimap) {
multimap.asMap().collectEntries {
[it.key, it.value.sort(false)]
}
}
为了更好的规范可读性,sortValues()
可能具有名称anyOrder()
,这将使断言看起来像:
expect:
anyOrder(actual) == anyOrder(expected)
然后,内部代码将评估每个条目并执行相应的操作 也测试内部对象。
这部分可以通过equals
方法在比较的每个对象类型上实现。