vlucas / frisby

Frisby is a REST API testing framework built on Jest that makes testing API endpoints easy, fast, and fun.

Home Page:http://frisbyjs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

JSONPath filter script expressions not working in .expect('json'...)

jkindwall opened this issue · comments

So I'm testing an api call that returns a json array of objects. I want to verify the name of the object in the list that was created by Bob. As it so happens, this object is currently the first one in the array, but it may not always be.

This works:

.expect('json', '[0].name', 'Bobs Object')

However, this does not:

.expect('json', '[?(@.createdBy == 'Bob')].name', 'Bobs Object')

This is a valid filter script expression as defined in the JSONPath standard. However, it doesn't seem to be supported, as I get the following failure:

Expected '?(@' not found (path '[?(@.createdBy=="Bob")].name')

I can probably get around this with a custom expect handler, but I would expect this to be built in to the framework.

There is no claim of support for any JSONPath syntax in Frisby.js. Some basic helpers are provided for more easily testing things like all items in an array, etc. but you are expecting something here that is not built-in, and not advertised anywhere.

@jkindwall

If you define Custom Expect Handlers you can easily use JSONPath.

The following is sample code. (use jsonpath package.)

const frisby = require('frisby');
const jp = require('jsonpath');

beforeAll(() => {
  frisby.addExpectHandler('jsonpath', (response, path, expected) => {
    let actual = jp.query(response.json, path);
    expect(actual).toEqual(expect.arrayContaining(expected));
  });
});

afterAll(() => {
  frisby.removeExpectHandler('jsonpath');
});

it('test JSONPath.', () => {
  return frisby.fromJSON([
    { name: "London", "population": 8615246 },
    { name: "Berlin", "population": 3517424 },
    { name: "Madrid", "population": 3165235 },
    { name: "Rome",   "population": 2870528 },
  ])
    .expect('status', 200)
    .expect('jsonpath', '$[?(@.name=="London")].population', [8615246]);
});

@vlucas Fair enough. I guess I was assuming a little too much when I interpreted the "path" parameter of the json expect handler to be implying full json-path support.

@H1Gdev Thanks. This is exactly the sort of thing I was thinking about, however the docs don't include custom expect handlers and the README doesn't show how to pass parameters to the custom expect handlers like this.

@jkindwall Sounds like we need to update the docs with a better example of adding your own expect handlers. We do have a small example, but it sounds like maybe it needs to be more full-featured. This example code from @H1Gdev will do nicely :)