java - How to create a custom domain specific assert/matcher in spock or hamcrest -


i trying write custom domain related assert/matcher in spock or hamcrest, not sure how proceed.

i tried writing custom matcher in hamcrest far has led me partial solution.

i looking guidance proper course in scenario be.

domain objects:

  • resultmap has object map < iline, iresult > - there 1 inoderesult associated each iline.
  • iresult has 4 (google guava) multimap objects need verified.

what in spock test like:

expect:   actualresultmap, matchesinanyorder(expectedresultmap)   or   actualresultmap, matches(expectedresultmap) // match if in same order. 

the internal code evaluate each entry , appropriate tests on inner objects well.

so far managed write part of code evaluates 1 set of multimap, not sure how chain tests.

custom matcher:

package com.ps.de.test.custommatcher  import org.hamcrest.basematcher  class multimapmatcher {      /**      * checks entries in multimap      * @param expected      * @return shows failure if entries not match or not in 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 ${expected}")                 },                 describemismatch: { actual, description ->                     description.appendtext("were ${actual}")                 }         ]   basematcher     }      /**      * checks entries in multimap      * @param expected      * @return shows failure if entries 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 ${expected}")                 },                 describemismatch: { actual, description ->                     description.appendtext("were ${actual}")                 }         ]   basematcher     } } 

testing custom matcher:

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 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 key/value         expected.put("fruits", "apple");         expected.put("fruits", "banana");         expected.put("fruits", "pear");         expected.put("vegetables", "carrot");          expect:          actual, hasallinanyorder(expected)         actual, hasallinorder(expected)     }      def "test hasallinanyorder"() {         multimap<string, string> actual = arraylistmultimap.create();          // adding 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 key/value         expected.put("fruits", "banana");         expected.put("fruits", "apple");         expected.put("fruits", "pear");         expected.put("vegetables", "carrot");          expect:         actual, hasallinanyorder(expected)         actual, not(hasallinorder(expected))     } } 

any or guidance appreciated.

why need custom matchers @ all? perhaps, spock , groovy powerful enough fulfil need without custom matchers.

to match 2 multimap objects have same content in same order enough do:

expected: actual == expected 

is there benefit in adding more code same assertion?

for match in order it's bit more tricky it's enough add sorting method (may extracted , reused within other test classes). like:

expected: sortvalues(actual) == sortvalues(expected) 

and method itself:

static map<string, collection<string>> sortvalues(multimap<string, string> multimap) {     multimap.asmap().collectentries {         [it.key, it.value.sort(false)]     } } 

perhaps better specification readability sortvalues() may have name anyorder() make assertion like:

expect: anyorder(actual) == anyorder(expected) 

the internal code evaluate each entry , appropriate tests on inner objects well.

this part can implemented equals method on each object type under comparison.


Comments

Popular posts from this blog

google api - Incomplete response from Gmail API threads.list -

Installing Android SQLite Asset Helper -

Qt Creator - Searching files with Locator including folder -