2015-12-05 5 views
7

私はspring-test統合テストの一環としてHamcrest CoreMatcherクラスを使用しています。私のJSONは次のようになります。JSONのdouble値を比較するHamcrest matcher

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

そして、私の統合テストは、次のようになります。

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))) 

しかし、アサーションは失敗します。

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

私は別のIsCloseToマッチャがここにありますことを知っている:http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/number/IsCloseTo.html 、それをそう使用する:

.andExpect(jsonPath("$.data[0].distanceInMiles", closeTo(miles, 0))) 
奇妙なエラーでの

結果:

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) 

私はエラーのいくつかの種類が含ますることを避けるために期待していた - 私は返された値が正確に4になりたいは、私がどれだけ多くの末尾を気にしませんゼロが含まれます。

+0

をJSONレスポンスのため、同じ変数を2回入力しないように再利用したいと考えていました。デモのためにコードブロックを更新します。 –

+0

ところでJava 8を使用していますか? – Tunaki

+0

はい、私はJava 8を使用しています。 –

答えて

2

問題は、一致がIntegerで実行され、2倍の値ではないことです。

あなたは正しくMatcher<Double>を与えています。 SpringはJaywayをJSONの解析に使用し、JSONパスはIntegerオブジェクトとして評価されます。 IntegerDoubleが常に等しくないため、一致は失敗します。

このように、Matcheris((int) miles)に変更する必要があります。

JSONを制御せずにdistanceInMilesが変更される可能性がある場合は、これが問題になります。ジェイウェイ氏はをDoubleとして解析します。"4"Integerとして解析します。この場合、IntegerDoubleの両方のオブジェクトを処理する独自のMatcherを実装して、TypeSafeMatcherを拡張する必要があります。

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; 
    } 

} 

ことが知られている二重の値に自分のdouble値を比較することにより、任意のNumberに一致します。これは単純な実装になります。

+0

残念ながら 'closeTo'は私にいくつかの本当に奇妙な問題を与えました。 –

+0

@CraigOtisはい、依然として予想されるタイプではないためです。私はHamcrestがタイプチェックをしていることを忘れていました。独自のマッチャーを実装する必要があります。 – Tunaki

+0

さて、心配する必要はありません - ありがとう! –

1

私は、デフォルトではfloatとして比較していることが判明し、そのような何かしてみてください:問題は `double`値は、その後の一部としてチェックされたモデルオブジェクトを作成するために使用されていることである

.body("field_with_double_value",is(100.0f));