skyscreamer / JSONassert

Write JSON unit tests in less code. Great for testing REST interfaces.
http://jsonassert.skyscreamer.org
Apache License 2.0
1k stars 197 forks source link

Allow field values to be ignored by specifying a JSON path #15

Open hertzsprung opened 12 years ago

hertzsprung commented 12 years ago

We often have a requirement where we're not interested in the value of a field, but we do care that the field exists. This might be an autogenerated ID or a timestamp for example.

It would be useful to specify the field(s) as a JSON path expression so that we can be selective in which fields get ignored.

sawyercade commented 8 years ago

+1 for a partial ignore feature

praveen133t commented 8 years ago

Extend DefaultComparator class. Override checkJsonObjectKeysExpectedInActual method. before calling the compareValues method just create an "if" condition to check if the 'key' is one of the item in the 'List' of items you wanna ignore. If "yes" then create a new "customCompareValues" method that will have your custom implementation. In my case I am not ignoring. I'm checking a few conditions like if ((expectedValue instanceof Number)) { if (actualValue == null || actualValue.equals("") || actualValue.equals(" ") || !(actualValue instanceof Number)) result.fail(prefix, expectedValue, actualValue); }

and more. Pls let me know if you need help

solvingj commented 8 years ago

+1 for partial ignore.

For what it's worth, in our case, something like what @praveen133t suggested would be best. Use instanceof to match any actual value types (strings/numbers/nulls/bools/etc or !array and !object) and then return skip the value comparison. Also as originally suggested, an extra boolean flag on the original signature for "comparevalues" seems the most simple, albeit not very flexible.

Also worth noting, in our case, we're less interested in the jsonpath functionality. We want to use JSONassert with lots of diverse object structures without defining the specifics of what to ignore.

Naveen1836 commented 8 years ago

Hi,

Apologies for asking same question again.

I have same requirement and have been googling from long time. i have read the comments but couldnt understand if the issue is fixed, or trying with some solution?

if fixed, can some one please let me know how to ignore fields.

praveen133t commented 8 years ago

@Naveen1836 : Pls see my reply (two posts above yours). I was able to implement something that way

Naveen1836 commented 8 years ago

@praveen133t: Can you send me the code, i mean class which you are extending that code to naveenavula1989@gmail.com

carterpage commented 8 years ago

Anyone want to submit a PR for partial ignore? I can add to 1.4.1.

bkdonline commented 7 years ago

Partial compare is a must have feature in the world of REST APIs. If we can merge this in time for 1.5.1, it would be very useful. @carterpage

benwaine commented 7 years ago

I found my way here looking for partial ignore but after reading @ittiel's solution I implemented my own comparator that looked for specific place holder tokens and did a different type of value comparison.

Trying validate this:

Expected: {"accountNumber": "<UUID>"}
Actual: {"accountNumber": "b14759a9-2840-44f9-84cd-2814a2069261"}
package com.cloudbank.account.endtoend;

import org.json.JSONException;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.skyscreamer.jsonassert.JSONCompareResult;
import org.skyscreamer.jsonassert.comparator.DefaultComparator;

import java.util.UUID;

public class DynamicValueTokenComparator extends DefaultComparator {

    public DynamicValueTokenComparator(JSONCompareMode mode) {
        super(mode);
    }

    @Override
    public void compareValues(String s, Object o, Object o1, JSONCompareResult jsonCompareResult) throws JSONException {

        // --- ! This could be a stack of things looking at tokens like <UUID> <DATE> etc

        // A dynamic UUID is expected
        if (o.toString().equals("<UUID>")) {
            // If yes then the corresponding UUID must be valid
            try {
                UUID.fromString(o1.toString());
            } catch (IllegalArgumentException e) {
                throw new JSONException("Invalid UUID for field " + s);
            }

            // Return - don't apply default value checking
            return;
        }

        super.compareValues(s, o, o1, jsonCompareResult);
    }
}

In the test:

JSONAssert.assertEquals(json, response.getBody(), new DynamicValueTokenComparator(JSONCompareMode.NON_EXTENSIBLE));
JavaOPs commented 6 years ago

Maybe it will be helpful: in my Spring controller tests I've made workaround for this problem: https://stackoverflow.com/a/47896806/548473

SrikarNanduri commented 6 years ago

+1 for this feature - I have a requirement for this feature

SrikarNanduri commented 6 years ago

I recently found this library JsonUnit which has the exact functionality check it out

arundharmar commented 6 years ago

I use this library and created an extended version for a custom Partial JSON assertion that I needed. I have that jar created for updated library in this location. Feel free to use it and to give me feedback on that.

VegetaPn commented 5 years ago

+1 for this feature. Any progress on this feature ?

Ripul89 commented 5 years ago

Hi All, I am not getting dependency for JAConstraint

dilipsonu commented 4 years ago

+1 for this feature