junit-json-params icon indicating copy to clipboard operation
junit-json-params copied to clipboard

automatic paramter conversion as Class in Input Method

Open vahidallahvakily opened this issue 6 years ago • 3 comments

Hi, Is it possible to use class instead of JsonObject as Method Input Parameter, For example:

@ParameterizedTest @JsonSource("{name:'test',family:'test'}") @DisplayName("provides an array of objects") void testObjectPerson(Person person) { ... }

Thanks in advance

vahidallahvakily avatar Jun 26 '19 12:06 vahidallahvakily

Not right now as far as I can tell, but this would be awesome. I think it could be possible using argument aggregation, and in theory you might be able to write something that did this automatically using JSON binding / Jackson / Gson.

Let me know how you go with it and also feel free to submit a PR if there’s something that seems to fit this library in this idea.

joshka avatar Jun 26 '19 15:06 joshka

Hi, I've solved the problem by just modifying your code a little bit I added a class JsonFileArgument as

public class JsonFileArgument {

    private Class cls;
    private String strObject;
   //Getter & Setter
}

I add convertor for JSON Conversion & Annotation as

public @interface JsonFileSource {

   String resource();

   Class clsObj();
}

public class JsonArgumentConvertor implements ArgumentConverter {

    @Override
    public Object convert(Object source, ParameterContext context) {
        if (!(source instanceof  JsonFileArgument)) {
            throw new ArgumentConversionException("Not a JsonFileArgument type");
        }
        ObjectMapper objectMapper=new ObjectMapper();
        JsonFileArgument jsonFileArgument= (JsonFileArgument)source;
        try {
            return objectMapper.readValue(jsonFileArgument.getStrObject(),jsonFileArgument.getCls());

        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

and Finally I Change JsonFileArgumentProvider as follow


@Override
    public Stream<? extends Arguments> provideArguments(ExtensionContext context) throws Exception 
  {
        List<String> lstResources=getResourceFiles(this.resourceDirectory);
        return lstResources.stream()
                .map(resource -> readStream(context,resource))
                .map(Arguments::of);

    }

 private JsonFileArgument readStream(ExtensionContext context, String resource) {
        try{
            Class<?> testClass = context.getRequiredTestClass();
            InputStream inputStream = inputStreamProvider.apply(testClass, resource);
            String strFileContent= IOUtils.toString(inputStream,"UTF-8");
            return new JsonFileArgument(this.clsObject,strFileContent);
        }catch (Exception ex){
            ex.printStackTrace();
            return new JsonFileArgument(this.clsObject);
        }

    }

let me know , what do you think about my changes.

vahidallahvakily avatar Jun 29 '19 07:06 vahidallahvakily

Hi, sorry that I missed seeing this comment until just now. Would you be interested in submitting a PR with some tests to show a bit more how this works? I really like this idea.

Please avoid the Hungarian notation style (clsXXX, strXXX). I find that it often makes code more difficult to read than without.

joshka avatar Aug 13 '19 16:08 joshka

Closing. See https://github.com/joshka/junit-json-params/issues/177 for more info.

joshka avatar Aug 20 '24 10:08 joshka