Как бы я протестировал этот код, основанный на обещаниях, с помощью jest? - PullRequest
0 голосов
/ 06 октября 2018

Как бы я протестировал этот код в шутку?Я хотел бы убедиться, что ошибка и успех пройденного обещания вызываются по мере необходимости.Я уверен, что это что-то простое, но это сводит меня с ума.Большое спасибо.

handleStatusChangeRequest (changeEntryStatus) {
  return changeEntryStatus().then(() => {
    this.handleStatusChangeSuccess()
  }).catch(err => {
    this.handleErrorDisplay(err)
  })
}

Ответы [ 4 ]

0 голосов
/ 08 октября 2018

Ответ, который у меня есть, выглядит так:

**Success tests
const instance = el.find(EntryToolBar).instance()
const spy = jest.spyOn(instance, 'handleStatusChangeSuccess')

await instance.handleStatusChangeRequest(() => Promise.resolve('cool man'))

expect(spy).toHaveBeenCalledTimes(1)

**Error tests
const instance = el.find(EntryToolBar).instance()
const spy = jest.spyOn(instance, 'handleErrorDisplay')

await instance.handleStatusChangeRequest(() => Promise.reject(Error('shit')))
expect(spy).toHaveBeenCalledTimes(1)

Как я уже говорил выше, методы handleStatusChangeSuccess и handleError еще тестируются, где с некоторыми снимками (они просто устанавливают состояние и визуализируют несколько разныхJSX).Я чувствую себя довольно хорошо по этому поводу.Я использую spys / mocks, но я тестирую функции реализации в другом месте.Достаточная

0 голосов
/ 07 октября 2018

Это может быть реорганизовано, но ради демонстрации я оставил повторяющиеся биты в.

В example.spec.js обратный вызов, changeEntryStatus, заглушается, чтобы вернуть обещание.Чтобы проверить, были ли вызваны другие методы экземпляра (this.method), они сначала проверяются, а затем запускаются утверждения на образце после запуска тестируемого метода.Узнайте больше в Jest Docs .(См. Мои мысли о методах насмешки тестируемого устройства внизу.)

Запустите пример на repl.it.

example.js:

class Example {
  handleStatusChangeRequest(changeEntryStatus) {
    return changeEntryStatus().then(() => {
      this.handleStatusChangeSuccess()
    }).catch(err => {
      this.handleErrorDisplay(err)
    })
  }

  handleStatusChangeSuccess() {
    console.log('stubbed handleStatusChangeSuccess')
  }

  handleErrorDisplay(error) {
    console.log('stubbed handleErrorDisplay:', error)
  }
}

module.exports = Example;

example.spec.js:

const Example = require('./entryStatus')
describe('handleStatusChangeRequest', () => {
  it('should run the changeEntryStatus callback', () => {
    const {handleStatusChangeRequest} = new Example()
    const stub = jest.fn().mockResolvedValue()

    handleStatusChangeRequest(stub)

    // must return because handleStatusChangeRequest is asynchronous
    return expect(stub).toHaveBeenCalled()
  });

  it('should call example.handleStatusChangeSuccess', async () => {
    const example = new Example()
    const stub = jest.fn().mockResolvedValue()
    example.handleStatusChangeSuccess = jest.fn()

    await example.handleStatusChangeRequest(stub)

    expect(example.handleStatusChangeSuccess).toHaveBeenCalled();
  })

  it('should call example.handleErrorDisplay', async () => {
    const example = new Example()
    const fakeError = { code: 'fake_error_code' }
    const stub = jest.fn().mockRejectedValue(fakeError)
    example.handleErrorDisplay = jest.fn()


    await example.handleStatusChangeRequest(stub)

    expect(example.handleErrorDisplay).toHaveBeenCalled()
    expect(example.handleErrorDisplay).toHaveBeenCalledWith(fakeError)
  });
});

Мнение об отказе от ответственности : методы издевательства над тестируемым устройствомзапах.Попробуйте проверить ожидаемые эффекты от вызовов handleStatusChangeSuccess и handleErrorDisplay вместо проверки, чтобы узнать, были ли они вызваны.Тогда даже не раскрывайте эти методы публично, если только потребителям класса не нужен доступ.

0 голосов
/ 07 октября 2018

Отказ от ответственности: Методы издевательства над тестируемым устройством - это запах.Попробуйте проверить ожидаемые эффекты вызова handleStatusChangeSuccess и handleErrorDisplay вместо проверки, чтобы узнать, были ли они вызваны.Тогда даже не раскрывайте эти методы публично, если только пользователям этого класса не нужен доступ.Мухи - это запах, поскольку тесты должны подтверждать поведение кода кода, а не его реализацию .Тестирование последнего делает код хрупким для изменения.

Сходя с моего мыла ... :) Мы ищем способ протестировать асинхронный метод.Я не уверен, какие утверждения ваши тесты должны сделать, чтобы проверить поведение внутри handleStatusChangeSuccess() и handleErrorDisplay(err), поэтому в приведенном ниже примере оставляется комментарий, куда эти утверждения будут добавлены.Следующее использует Promise.resolve() и Promise.reject() для запуска результатов тестирования.Я использовал async / await, у Jest есть других примеров асинхронности в их документах .

const Example = require('./example')

describe('handleStatusChangeRequest', () => {
  it('should resolve successfully', async () => {
    const {handleStatusChangeRequest} = new Example();
    const resolvePromise = () => Promise.resolve();

    await handleStatusChangeRequest(resolvePromise);

    // resolution assertions here
  });

  it('should resolve errors', async () => {
    const {handleStatusChangeRequest} = new Example();
    const fakeError = new Error('eep');
    const rejectPromise = () => Promise.reject(fakeError);

    // if your method doesn't throw, we can remove this try/catch
    // block and the fail() polyfill
    try {
      await example.handleStatusChangeRequest(rejectPromise);

      // if we don't throw our test shouldn't get here, so we
      // polyfill a fail() method since Jest doesn't give us one.
      // See https://github.com/facebook/jest/issues/2129
      expect(true).toBe(false);
    }
    catch (e) {
      // rejection assertions here
    }
  });
});
0 голосов
/ 06 октября 2018

Если ваш код использует обещания, есть хороший способ обработки асинхронных тестов.Просто верните promise из вашего теста, и Jest будет ждать разрешения этого promise.
Если обещание будет отклонено, тест автоматически провалится.

Например, предположим, что changeData вместо использования обратного вызова возвращает promise, который должен преобразовываться в строку «статус был успешно изменен» .

Обязательно return promise - если вы пропустите это выражение возврата, ваш тест будет завершен до выполнения changeData() - [ асинхронной функции ]завершает.

Вот удобный и простой в использовании шаблон

test('if the data is changed', () => {
  return changeData().then((data) => {
    expect(data).toBe('status has been successfully modified');
  });
})

Счастливого тестирования:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...