Java – hamcrest matcher compares the double value of JSON

I am using the hamcrest corematcher class as part of the spring test integration test My JSON looks like:

{"data":[{"distanceInMiles":4,"id":"f97236ba-f4ef-4...

My integration tests look like:

double miles = 4.0
Activity a = new BasicActivity(miles);
this.activityManager.add(a); // A mock activity manager (in-memory)
...
this.mockmvc.perform(get("/").accept("application/json"))
    .andExpect(jsonPath("$.data[0].distanceInMiles",is(miles)))

However, the assertion failed:

java.lang.AssertionError: JSON path "$.data[0].distanceInMiles"
Expected: is <4.0>
     but: was <4>
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)

I know there is a separate iscloseto matcher: http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/number/IsCloseTo.html , but use it like this:

.andExpect(jsonPath("$.data[0].distanceInMiles",closeTo(miles,0)))

Causes a strange error:

java.lang.AssertionError: JSON path "$.data[0].distanceInMiles"
Expected: a numeric value within <0.0> of <4.0>
     but: was a java.lang.Integer (<4>)
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)

I want to avoid including some kind of error - I want to return a value of exactly 4, I just don't care how many trailing zeros I include

Solution

The problem is that matching is performed on integers, not on double values

You correctly gave matcher < < double > Spring uses jayway to parse JSON, and your JSON path will be evaluated as an integer object Matching will fail because integer and double are always unequal

Therefore, you need to change the matcher to ((int) miles)

This is even more problematic if you don't control the JSON you're getting and distanceinmiles may change Jayway parses "4" as an integer, but it parses "4.0" as a double In this case, you will have to implement your own matcher by extending typesafematcher to handle integer and double objects This will be a simple implementation:

class NumberMatcher extends TypeSafeMatcher<Number> {

    private double value;

    public NumberMatcher(double value) {
        this.value = value;
    }

    @Override
    public void describeTo(Description description) {
        // some description
    }

    @Override
    protected boolean matchesSafely(Number item) {
        return item.doubleValue() == value;
    }

}

It matches any number by comparing their double value with the known double value

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>