Skip to content

Input from test.json does not pass a simple string to java method correctly #126

Open

Description

@mklaehn

Considering the following function class

public class PojoFunction {
    public Object greet(String name) {
        if (name == null || name.isEmpty()) {
            name = "World";
        }
        return new Greeting(name);
    }
    public static class Greeting {
        public final String name;
        public Greeting(String name) {
            this.name = name;
        }
    }
}

and this content for test.json

{
    "tests": [
        {
            "input": {"body": "Johnny"},
            "output": {"body": {"name": "Johnny"}}
        }
    ]
}

causes a test failure.

Test fails due to the String value in the greet function being of the value "Johnny" instead of value Johnny.

Console output:

FAILED           mismatched output found.
                 expected:
                 {"name":"Johnny"}
                 got:
                 HTTP/1.1 200 INVOKED
                 Content-Type: application/json
                 Content-length: 21
                 
                 {"name":"\"Johnny\""}

Activity

  1. zootalures commented on Feb 28, 2018

    @zootalures
    Member

    Thanks for raising. This is intended behaviour (see explanation below)

    Looking a bit deeper the verbatim frame being sent to the container is :

                     POST hello
    		 Content-Length: 8
    		 Content-Type:  application/json
    ....
    
    		 "Johnny"
    

    The CLI is sending a raw json doc of "Johnny" which the FDK is trying to coerce to a string.

    The FDK coerces inputs to paramers based on a set of (configurable) coercion rules based on the type of the parameter and (e.g.) the content type of the input.

    When the content type is application/json and the param type is a String, the FDK has a choice of either giving you the raw JSON doc ("Johnny") or to assume that the doc is only a JSON string (and not an object or number or array) and to unmarshal it , giving you the JSON value Johnny

    We chose the former (Strings and byte array parameter types are assumed to be copies of the body of the request) as it creates more intuitive behaviour when the doc is an object (which would otherwise cause JSON error).

    You can override this behaviour (always prefer JSON unmarshalling):

    Import the FDK runtime as a maven runtime dep.

      <dependency>
                <groupId>com.fnproject.fn</groupId>
                <artifactId>runtime</artifactId>
                <version>${fnproject.version}</version>
            </dependency>
    

    In your function add an @InputBinding annotation to the input parameter that forces the JacksonCoercion (this will then skip string coercion)

      import com.fnproject.fn.runtime.coercion.jackson.JacksonCoercion; 
      import com.fnproject.fn.api.InputBinding; 
    
      public Object greet(@InputBinding(JacksonCoercion.class) String name) {
    

    Hope that helps

  2. mklaehn commented on Mar 1, 2018

    @mklaehn
    Author

    Ok. It helped as far a the generated JSON to look the same as the JSON declared as the body in the test. What it does not help is in succeeding the test.

    The full output, I've cut it to size previously due to the "obvious" discrepancy in the expected JSON body output.

    Test 1
    In gomega FailHandler: Actual 'HTTP/1.1 200 INVOKED
    Content-Type: application/json
    Content-length: 17
    
    {"name":"Johnny"}' should be valid JSON, but it is not.
    Underlying error:invalid character 'H' looking for beginning of value
    FAILED           mismatched output found.
                     expected:
                     {"name":"Johnny"}
                     got:
                     HTTP/1.1 200 INVOKED
                     Content-Type: application/json
                     Content-length: 17
                     
                     {"name":"Johnny"}
                     logs:
                     
     -    ( 1.352177808s )
    

    To me it looks like that the evaluation of the response does not extract the response body correctly in order to check against the expected body (as declared in file test.json).

  3. zootalures commented on Mar 1, 2018

    @zootalures
    Member

    yeah this looks like an issue with the cli - fnproject/cli#184

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions