Sinon - шпион не вызывается, но тест входит в функцию - PullRequest
0 голосов
/ 25 сентября 2018

Я сделал тест для функции с двумя заглушками, фактически заглушки работают, и если я console.log res.json или next в любой части функции, он показывает объекты-шпионы внутри.В любом случае, шпион не вызывается, когда я делаю утверждение, в котором говорится: «Ожидаемый шпион был вызван хотя бы один раз, но никогда не был вызван».Программа работает, но тест сумасшедший.Помогите мне, пожалуйста!

У меня есть такая функция:

export function createOrUpdateToken(req, res, next) {
  const { code, redirect_uri, realm_id, quickbooksAuth } = req.body;

  if (!code || !redirect_uri || !realm_id) {
    const message = 'Authorization code, Redirect URI and Realm Id are required';
    return next(new CustomError('Bad Request', message, 400));
  }
  return issueRefreshTokenBasedOnAuthorizationCode(
    {
      redirect_uri,
      authorizationCode: code,
      authorization: quickbooksAuth,
    })
    .then((response) => {
      const { body: { refresh_token } } = response;
      return securityModel.findOneAndUpdate(
        { realmId: realm_id },
        { refreshToken: refresh_token },
        { upsert: true },
        (err) => {
          if (err) return next(err);
          return res.json('Authentication successfull');
        });
    })
    .catch((err) => {
      return next(err);
    });
}

И тест такой:

it('Should create or update token', () => {
  req.body = {
    code: '1234',
    redirect_uri: 'www.test.com',
    realm_id: '12345',
    quickbooksAuth: 'dhajksdas.dsajdosaiudjsa.dsaojpdas'
  };
  sinon
    .stub(intuit, 'issueRefreshTokenBasedOnAuthorizationCode')
    .resolves({
      body: {
        refresh_token: 'hjdklasdashda.dsa.dasdsa.dasddasdas'
      }
    });

  sinon
    .stub(securityModel, 'findOneAndUpdate')
    .withArgs({ realmId: req.body.realm_id },
      { refreshToken: 'hjdklasdashda.dsa.dasdsa.dasddasdas' })
    .yields(null);
  createOrUpdateToken(req, res, next);
  sinon.assert.called(res.json);
});

Условия:

beforeEach(() => {
      res = {
        json: sinon.spy()
      };
      next = sinon.spy();
    });

    afterEach(() => {
      sinon.restore();
    })

1 Ответ

0 голосов
/ 26 сентября 2018

Issue

createOrUpdateToken выполняет некоторый асинхронный код, который не завершился к моменту его возвращения, и sinon.assert.called(res.json) запускается и завершается с ошибкой.

Решение

Выуже возвращая обещание от createOrUpdateToken, поэтому просто сделайте ваш тест async и await обещание перед выполнением утверждения:

it('Should create or update token', async () => {  // make the test function async
  req.body = {
    code: '1234',
    redirect_uri: 'www.test.com',
    realm_id: '12345',
    quickbooksAuth: 'dhajksdas.dsajdosaiudjsa.dsaojpdas'
  };
  sinon
    .stub(intuit, 'issueRefreshTokenBasedOnAuthorizationCode')
    .resolves({
      body: {
        refresh_token: 'hjdklasdashda.dsa.dasdsa.dasddasdas'
      }
    });

  sinon
    .stub(securityModel, 'findOneAndUpdate')
    .withArgs({ realmId: req.body.realm_id },
      { refreshToken: 'hjdklasdashda.dsa.dasdsa.dasddasdas' })
    .yields(null);
  await createOrUpdateToken(req, res, next);  // await the returned Promise
  sinon.assert.called(res.json);  // SUCCESS
});
...