labd / commercetools-node-mock

Mock for the commercetools rest api
MIT License
19 stars 14 forks source link

Provide more examples or test cases #13

Open ahmetoz opened 3 years ago

ahmetoz commented 3 years ago

Hey,

The library looks interesting and might help us to reduce lots of boilerplate test code.

I tried the example in the readme but unfortunately, it did not work for me, could you provide more examples of how it could be used, I could not see any tests in a project to inspire.

Regards, Ahmet.

ahmetoz commented 3 years ago

Oh, I see now the tests are added into the src folder 😄 I will check those files.

ahmetoz commented 3 years ago

@davidweterings sorry to ping but could not get any help yet.

I'm trying to mock a scenario that a post would return with failure like 500 or 409, is that possible with this library? I was using nock for that purpose but looks like the existing code always returns 200 for the drafts for post requests?

davidweterings commented 3 years ago

@ahmetoz no worries. You can easily get 409s by sending the wrong version. F.e.:

import assert from 'assert'
import { InventoryEntry } from '@commercetools/platform-sdk'
import supertest from 'supertest'
import { CommercetoolsMock } from '../index'

describe('Inventory Entry Update Actions', () => {
  const ctMock = new CommercetoolsMock()
  let inventoryEntry: InventoryEntry | undefined

  beforeEach(async () => {
    let response = await supertest(ctMock.app)
      .post('/dummy/inventory')
      .send({
        sku: '1337',
        quantityOnStock: 100,
      })
    expect(response.status).toBe(200)
    inventoryEntry = response.body
  })

  it('conflict', async () => {
    assert(inventoryEntry, 'inventory entry not created')

    const response = await supertest(ctMock.app)
      .post(`/dummy/inventory/${inventoryEntry.id}`)
      .send({
        // wrong version
        version: 20,
        actions: [{ action: 'changeQuantity', quantity: 300 }],
      })

    expect(response.status).toBe(409)
  })
})

500's are harder to create/not really the point of this library (which is to mock the CT api). Usually the CT api gives back 400's on invalid or incorrect POST data. I'm not sure what your use case is for specific 500 errors.

ahmetoz commented 3 years ago

Hey, @davidweterings thanks for the reply 👍🏽

I saw that kind of scenario in test files, but if I am sending the request inside my code and not in the test, can I mock those requests by using the library?

I think mocking the usual scenarios within the library looks nice and covers most API calls, but in unit tests, we also need to ensure cases such as reasoning the code flow in the exception handlers. I could only see that all requests are backed by in-memory storage and those are mocked already as successful, do you see any way to mock requests?

davidweterings commented 3 years ago

@ahmetoz we're still figuring out what to use this for and what cases we can / should handle. If you have a suggestion/concrete example (and a PR ;)?) we can take a look.

I can imagine something like this where you explicitly tell ctMock what the next response should be like. This could then possilby also be used to delay responses, fake timeouts.

  it('handles error', async () => {
    assert(inventoryEntry, 'inventory entry not created')

    ctMock.setNextRequestResponse(409, 'version conflict')

    const response = await supertest(ctMock.app)
      .post(`/dummy/inventory/${inventoryEntry.id}`)
      .send({
        version: 1
        actions: [{ action: 'changeQuantity', quantity: 300 }],
      })

    expect(response.status).toBe(409)
  })
ahmetoz commented 3 years ago

Hi, @davidweterings as explained this scenario could be anything you want to unit test the exception flow, for instance you have a logic that you want to update actions with the correct version when API fails with 409.

So manipulating the nock instance with a ctMock callback would be nice to have, unfortunately, I don't have time to prepare a PR for that, as I am not really familiar with the library and this looks like a core change. Here your proposal with setNextRequestResponse could make sense, but in this case, you need to consider reverting mock instance to the success path on the second retry.