Giter VIP home page Giter VIP logo

approvalcrest's Introduction

Approvalcrest

'Approvalcrest' is a library that extends the functionality of Shazamcrest.

Assertions on complete beans are made simpler by serialising the actual and expected beans to json, and comparing the two. The diagnostics are leveraging the comparison functionality of IDEs like Eclipse or IntelliJ.

Usage

sameBeanAs

Having a Person bean with the following structure:

Person person
    |-- String name
    |-- String surname
    |-- Address address
        |-- String streetName
        |-- int streetNumber
        |-- String postcode

to compare two Person beans with Approvalcrest we would write:

assertThat(actualPerson, sameBeanAs(expectedPerson));

instead of explicitly match every field of the bean and sub-beans:

assertThat(actualPerson, allOf(
        hasProperty("name", equalTo(expectedPerson.name)),
        hasProperty("surname", equalTo(expectedPerson.surname)),
        hasProperty("address", allOf(
            hasProperty("streetName", equalTo(expectedPerson.address.streetName)),
            hasProperty("streetNumber", equalTo(expectedPerson.address.streetNumber)),
            hasProperty("postcode", equalTo(expectedPerson.address.postcode)))
        )
    ));

sameJsonAsApproved

Creating the expected beans like the Person bean above can be a cumbersome task especially in more complex cases. sameJsonAsApproved meant to help with this task, instead of creating the expected bean to match against, it serializes the actual bean to json on the first run, and stores it in a file. By verifying and renaming the file, the user approves the content thus creating the expectations. Every additional run will use the file as the expected bean.

sameContentAsApproved

Error Messages

If the person address streetName does not match the expectations, the following diagnostic message is displayed:

org.junit.ComparisonFailure: address.streetName
        Expected: Via Roma
    got: Via Veneto
        expected:<... "streetName": "Via [Roma]",
    "streetNumber...> but was:<... "streetName": "Via [Veneto]",
    "streetNumber...>

The exception thrown is a ComparisonFailure which can be used by IDEs like Eclipse and IntelliJ to display a visual representation of the differences.

Comparison failure diagnostic

Note: in order to get the ComparisonFailure on mismatch the "assertThat" to use is com.github.karsaig.approvalcrest.MatcherAssert.assertThat rather than org.hamcrest.MatcherAssert.assertThat

Ignoring fields

If we are not interested in matching the street name, we can ignore it by specifying the field path:

assertThat(actualPerson, sameBeanAs(expectedPerson).ignoring("address.streetName"));

If we want to match the address only by the postcode, we can ignore street name and number by specifying the fields name pattern:

assertThat(actualPerson, sameBeanAs(expectedPerson).ignoring(startsWith("street")));

where startsWith is an Hamcrest matcher.

Custom matching

If we want to make sure that the street name starts with "Via" at least:

assertThat(actualPerson, sameBeanAs(expectedPerson).with("address.streetName"), startsWith("Via"));

Circular references

Having a Shop bean with the following structure:

Shop shop
	|-- String name
    |-- Store store
        |-- Boss boss
            |-- Clerk clerk
                |-- Store store
                |-- Boss boss

Comparing two Shop objects throws a StackOverflowError, because of the cycles Clerk -> Store -> Boss -> Clerk and Clerk -> Boss -> Clerk.

From version 0.10 the circular reference is detected automatically and the serialiser is instructed to serialise the instance once and replace all the other occurrences with a pointer:

assertThat(actualShop, sameBeanAs(expectedShop));

produces the following representation:

{
  "store": {
    "0x1": {
      "0x1": {
        "0x1": {
          "boss": "0x2"
        }
      }
    },
    "0x2": {
      "0x1": {
        "0x1": {
          "clerk": {
            "boss": "0x2",
            "store": "0x1"
          }
        }
      }
    }
  },
  "name": "shop"
}

QuickStart

To use add the following to your project's pom.xml:

<dependency>
	<groupId>com.github.karsaig</groupId>
	<artifactId>approvalcrest</artifactId>
	<version>0.15</version>
</dependency>

approvalcrest's People

Contributors

bdupreez avatar gerbrand avatar jarcionek avatar jideji avatar jtheory avatar karsaig avatar lucanaldini avatar ratshidaho avatar tddmonkey avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.