meeshkan / unmock-js

Fuzz test your REST API calls
https://unmock.io
93 stars 8 forks source link

Using u.oneOf Breaks Unmock Response #399

Closed shaabans closed 4 years ago

shaabans commented 4 years ago

Hi, I'm not sure if this is just a dumb question or if it should be a bug. I'm using version 0.3.16, and trying something like this to mock an Axios API in a React Native project:

import unmock, { u } from 'unmock';

unmock
  .nock("https://...", "myApi")
  .get("/cases")
  .reply(200, {
    status: "ok",
    cases: [{
      id: u.integer(),
      user_id: u.integer(),
      gender: u.oneOf("male", "female"),
      age: u.integer(),
      status: u.oneOf("current", "archived")
    }]);

The results coming back don't seem to be fully resolved into final values, for example:

  [
      {
        id: { type: 'integer', dynamic: 'ut' },
        user_id: { type: 'integer', dynamic: 'aute' },
        gender: { oneOf: 'male', dynamic: 'deserunt proident ad dolor cillum' },
        age: { type: 'integer', dynamic: 'proident' },
        status: { oneOf: 'current', dynamic: 'dolore quis ex dolor exercitation' },
      }
  ]

The test itself looks like this:

import React from 'react';
import App from '../App';
import { fireEvent, render, wait, waitForElement } from '@testing-library/react-native';
import unmock, { runner, transform, u } from 'unmock';

jest.mock('react-native-image-picker', () => ({ }));

beforeAll(() => {
  unmock.on();
  unmock
    .nock("https://peer-live-stage.nurelm.com/api", "peerApi")
    .get("/cases")
    .reply(200, {
      status: "ok",
      cases: [{
        id: u.integer(),
        user_id: u.integer(),
        gender: u.oneOf("male", "female"),
        age: u.integer(),
        status: u.oneOf("current", "archived"),
      }]
    //... plus a few more endpoints I left out to keep this short ...
    });
});

beforeEach(() => {
  unmock.reset();
});

describe('App Component', () => {
  describe('When a user trys to log in', () => {
    test('they go to live cases screen when the user/pass are valid', async () => {
      // Get the top level App element
      const { getByText, getByLabelText, getByTestId } = render(<App />);

      // Click the Login button on the onboarding screen
      const loginButton1 = await waitForElement(() => getByText('Login'));
      fireEvent.press(loginButton1);

      // Find user / pass fields and login button
      const [userField, passField, loginButton2] = await waitForElement(() => [
        getByLabelText('Email'),
        getByLabelText('Password'),
        getByText('Login')
      ])

      // Fill in the user/pass fields with silly text, tell Unmock to return
      // a valid response
      fireEvent.changeText(userField, 'SomeUsername');
      fireEvent.changeText(passField, 'SomePassword');
      fireEvent.press(loginButton2);

      // Look for "Live Cases" header
      const invalidLogin = await waitForElement(() => getByText(/cases/i));
    }, 30000);
  });

});

Thanks in advance for any tips, and for the great testing tool!

shaabans commented 4 years ago

I added the actual test in the description, in case it helps spot any issues. Another odd thing I noticed is that using jest-reporter generates a report showing 1 test with NO http calls, which isn't right because I can clearly unmock data being returned, it's just malformed as shown in the description.

shaabans commented 4 years ago

Ah ha, after a solid day of bang-head-against-wall, I finally started experimenting and found that removing 'gender: u.oneOf("male", "female")' from my response definition made the generated responses begin working properly again, even though that's one of the supported json-scheme-poet functions.

shaabans commented 4 years ago

And, finally, I see my error: u.oneOf('male', 'female') is wrong, since it sound accept an array. Using u.oneOf(['male', 'female']) is right and works.

This either fails silently, or causes really strange results, so I guess a more graceful failure could be a good feature to consider.

mikesol commented 4 years ago

Glad you found the solution! I'm the author of json-schema-poet - the documentation is pretty bad, so I'll try to add function signatures to it. One question @shaabans - are you using typescript? If not, does your IDE show the function signature for those functions? I work mostly in typescript & VSCode, so the more feedback I can get from devs using other environments, the better I can make the library. Thanks!

mikesol commented 4 years ago

https://github.com/meeshkan/json-schema-poet/issues/10

shaabans commented 4 years ago

Hey Mike, thanks for the reply and the hard work on this project, it's a great tool.

We're using ES6 (although considering TypeScript), and I don't see function signatures while using Atom (haven't tried in VSCode).