axios-mock-adapter icon indicating copy to clipboard operation
axios-mock-adapter copied to clipboard

Support matching query params for `post`, `put` methods.

Open thk2b opened this issue 7 years ago • 8 comments

This PR closes #88 and #129.

Currently, it is possible to expect query params for GET, or a specific body for POST, but it is impossible to expect specific query params and a specific body.

To solve this, I added a fourth argument to MockAdapter.prototype[methodName] (ie. onPost, onGet), which corresponds to the expected query parameters for the request. This allows matching both a body and parameters for methods that have a body (PUT, POST, ...).

This is entirely backwards compatible, meaning that we can still match the params for GET, DELETE, etc... by specifying the expected params as the second argument (in place of the expected body as for PUT and POST methods). Overall, this PR does not affect the behaviour of the current public api, since it only adds an argument.

This test case demonstrates the new behaviour:

it('can pass a body, query params, and headers to match a handler', function() {
  var headers = {
    Accept: 'application/json, text/plain, */*',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Header-test': 'test-header'
  };
  mock.onPost('/withBodyAndParams', { data: { is: 'passed' }, in: true }, headers, { foo: 'bar', bar: 'baz' }).reply(200);
  
  return instance
    .post('/withBodyAndParams', { data: { is: 'passed' }, in: true }, { headers: headers, params: { foo: 'bar', bar: 'baz' }})
    .then(function(response) {
      expect(response.status).to.equal(200);
    });
});

Implementing this required adding the expected request parameters to the handler array. All indexes throughout the source were incremented as needed. Then, we check that the params do match in utils.findHandler.

I added several new test cases.

I also modified some tests involving matching params, where the expected params were passed inside the params key of an object. This was not required, and I'm not sure why the tests passed in the first place. See this commit.

thk2b avatar Apr 21 '18 01:04 thk2b

@ctimmerm , can you let me know if anything can be improved or if there is a problem with the PR? Thanks !

thk2b avatar Apr 26 '18 16:04 thk2b

@ctimmerm Hello Colin,

Again, may I get some feedback on this PR ? I'd really like to get this merged. If something is wrong please let me know and I will work on it.

Thank you for your time !

thk2b avatar May 03 '18 15:05 thk2b

@ctimmerm @thk2b It'd be great to get this feature in! Usage of params with POST/PUT requests shows up in the Axios docs and I'm sure many developers need this feature to properly filter which requests to mock.

Right now my not-so-great-work-around without this feature is to check the params in the reply

    mock.onPost(/\/path.+/).reply(function(config) {
      return new Promise(function(resolve, reject) {
        if (config.params 
            && config.params.querytype === 'javascript'
            && config.params.action === 'profile') {
          headers.qid = config.params.qid;
          resolve([200, responseBody, headers]);
        }
        else
          // this is not what I want to do, since this triggers the .catch() method.  
          // If this work-around functioned as I would like, I would need to trigger a passThrough,
          // rather than reject().   The proper implementation would be to support params with onPost()
          reject();  
      })
    });

Since I have no way to trigger a passThrough within the reply, I need the ability to filter up front as a part of the onPost call with params.

clockworked247 avatar Dec 20 '18 00:12 clockworked247

Thanks, @clockworked247 (and @thk2b). For posterity, here's how I handled mine (stripped down version) with Jest snapshots. I only need to ensure the correct data is being sent.

it('example test', () => {
  let actualData
  mock.onPost(url).reply(config => {
    actualData = config.data
    return new Promise(resolve => resolve([200, responseBody, headers]))
  })

  return store.dispatch(fnToTest()).then(() => {
    expect(JSON.parse(actualData)).toMatchSnapshot()
  })
})

jDeppen avatar Mar 02 '19 14:03 jDeppen

Should #88 or #129 be reopened since this never got merged?

keeganwitt avatar Apr 07 '21 15:04 keeganwitt

Do you know when this feature will be merged?

renanzulian avatar May 20 '21 18:05 renanzulian

Any news if or when this does get merged?

mvitz avatar Feb 24 '22 10:02 mvitz

any news? it's like 2023 already.

nasyarobby avatar Feb 17 '23 15:02 nasyarobby