Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSW: Overwriting mock object returned by the generated mock factory function. #822

Closed
atobaum opened this issue Apr 11, 2023 · 7 comments · Fixed by #1182
Closed

MSW: Overwriting mock object returned by the generated mock factory function. #822

atobaum opened this issue Apr 11, 2023 · 7 comments · Fixed by #1182
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@atobaum
Copy link

atobaum commented Apr 11, 2023

Hi, I'm using the generated mock factory function directly in test files and overwriting its properties to set up a proper test environment.

I wonder if is there any plan to solve this situation in the library like as follows.

// before
var getUserMock = function () { return ({
  name: facker_1.facker.random.word(),
  id: facker_1.facker.random.word()
}); };

// after
var getUserMock = function (value) { return ({
  name: facker_1.facker.random.word(),
  id: facker_1.facker.random.word(),
  ...value,
}); };

// usage
handler: [rest.get("/user", getUserMock({name: "some name to overwrite"}))]

If you don't have any plans or don't think that it's not the library to do, I would do it in my codebase.

@andersonvom
Copy link
Contributor

Bumping this thread with other examples: it'd be great if the generated code allowed for overrides as mentioned in the issue description. Currently, we get something similar to this:

// Foo.ts
interface Foo {
  id: number;
  name: string;
  items: string[];
}

// generated code
export const getFooMSW = () => [
  rest.post('*/foo/:fooId', (_req, res, ctx) => {
    return res(
      ctx.delay(1000),
      ctx.status(200, 'Mocked status'),
      ctx.json(getGetFooMock())
    );
  }),
];

// usage
mswServer.use(...getFooMSW());

Which is pretty handy when the test does not care about the specifics of Foo, but often it's necessary to have specific attributes in order to test different scenarios, which renders the generated code almost useless. It'd be great to be able to do these two things:

// test-1: ensure "some-name" is displayed
const foo1 = getGetFooMock({name: "some-name"});
mswServer.use(...getFooMSW(foo1));

// test-2: ensure some empty state is rendered when `items` is empty
const foo2 = getGetFooMock({items: []});
mswServer.use(...getFooMSW(foo2));

Being able to override objects this way would massively improve re-usability of the generated code without have to copy/paste functions to achieve the same behavior or without having to re-write how mocks are generated in the config file.

@melloware melloware changed the title Overwriting mock object returned by the generated mock factory function. MSW: Overwriting mock object returned by the generated mock factory function. Nov 14, 2023
@melloware melloware added the enhancement New feature or request label Nov 28, 2023
@soartec-lab
Copy link
Member

That's a good suggestion!

I would like to work on this response. First, I would like to be able to overwrite the response data in the mock settings.

@melloware
Copy link
Collaborator

@soartec-lab assigned to you!

@soartec-lab
Copy link
Member

soartec-lab commented Jan 27, 2024

I separate mock handler functions and aggregate functions. That way you can just use separate handlers. This will result in more reusable mocks.

// Individual handler
export const getListPetsMockHandler = http.get('*/pets', async () => {
  await delay(1000);
  return new HttpResponse(JSON.stringify(getListPetsMock()),
    { 
      status: 200,
      headers: {
        'Content-Type': 'application/json',
      }
    }
  )
})

export const getCreatePetsMockHandler = http.post('*/pets', async () => {
  await delay(1000);
  return new HttpResponse(null,
    { 
      status: 200,
      headers: {
        'Content-Type': 'application/json',
      }
    }
  )
})

export const getShowPetByIdMockHandler = http.get('*/pets/:petId', async () => {
  await delay(1000);
  return new HttpResponse(JSON.stringify(getShowPetByIdMock()),
    { 
      status: 200,
      headers: {
        'Content-Type': 'application/json',
      }
    }
  )
})

// handlers aggregation
export const getPetsMock = () => [
  getListPetsMockHandler,
  getCreatePetsMockHandler,
  getShowPetByIdMockHandler
]

@melloware

Hi, please let me know your opinion on this. What do you think about above?

@soartec-lab
Copy link
Member

I created PR, so could you review?

#1182

@melloware melloware added this to the 6.24.0 milestone Jan 27, 2024
@Will-Mann-16
Copy link
Contributor

Have reviewed, looks like a really good suggestion.

@soartec-lab
Copy link
Member

thank you for review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants