Проверка кода: это чистый способ написания модульного теста для исключения должен быть брошен случай? - PullRequest
0 голосов
/ 11 сентября 2018

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

it('should throw exception if config.env.json is malformed', async () => {
  // Arrange: beforeEach
  const fakeFsStub = sinon.stub(File, 'readFileAsyc');
  fakeFsStub.withArgs('./src/configuration/config.json').returns(mockConfig);
  fakeFsStub.withArgs('./src/configuration/config.test.json').returns(FakePromise.resolve(`{"key"}`));

  try {
    // Act
    await Configuration.getConfiguration('test');
    chai.assert.fail('test case failed: [should throw exception if config.env.json is malformed]');
  } catch (e) {
    // Assert
    chai.assert.equal('SyntaxError: Unexpected token } in JSON at position 6', e + '');
  }
});

Ответы [ 3 ]

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

делая функцию асинхронной, означает, что она будет возвращать обещание вместо немедленного значения.

Таким образом, с помощью chai-as-обещано вы можете сделать так:

it('should throw an exception', async () => {
    await expect(Configuration.getConfiguration('test')).to.eventually.be.rejectedWith(Error, 'SyntaxError: Unexpected token }');
});

Также, на мой взгляд, вы действительно проверяете, хорошо ли работает JSON.parse, а не тестируете свой собственный код.

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

Я тоже хочу добавить свой собственный ответ :) Я закончил рефакторинг своего теста, следуя предложенным здесь предложениям https://codereview.stackexchange.com/questions/203520/writing-unit-tests-for-exception-should-be-thrown-case

Также мне нравится предложение о принятом ответе.Я мог бы использовать это при написании моих будущих тестов.

it('should throw exception if config.env.json is malformed', async (done) => {
  // Arrange: beforeEach
  const fakeFsStub = sandbox.stub(File, 'readFileAsyc');
  fakeFsStub.withArgs('./src/configuration/config.json').returns(mockConfig);
  fakeFsStub.withArgs('./src/configuration/config.test.json').returns(FakePromise.resolve(`{"key"}`));

  chai.assert.throws(() => {
    // Act
    Configuration.getConfiguration('test').catch((e) => {
      chai.assert.instanceOf(e, SyntaxError);
      chai.assert.isTrue(e.toString().startsWith('SyntaxError: Unexpected token } in JSON'));
      done();
    });
  });
});
0 голосов
/ 11 сентября 2018

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

describe("Configuration class", ()=>{
  describe("#getConfiguration", ()=>{
    describe("When the config.env is correctly formed.", ()=>{
      // do some setup and assertions
    })
    describe("when the config.env.json is malformed", () =>{
      let actualError
      let fakeFsStub
      before(async ()=>{
        fakeFsStub = sinon.stub(File, 'readFileAsyc');
        fakeFsStub.withArgs('./src/configuration/config.json').returns(mockConfig);
        fakeFsStub.withArgs('./src/configuration/config.test.json').returns(FakePromise.resolve(`{"key"}`));

        try {
          await Configuration.getConfiguration('test');
        } catch (e) {
          actualError = e;
        }
      })

      it('should call fs.readFileAsyc with correct args', ()=>{
        // make an assertion
      })
      it('should throw an exception', () => {
        chai.assert.equal('SyntaxError: Unexpected token } in JSON at position 6', actualError + '');
      });
    })
  })
})

Это именно тот способ, которым я предпочитаю писать модульные тесты, потому что он сохраняет мое единственное утверждение.Это делает его полезным, когда вы видите, что тест не пройден, и вы точно знаете, какое утверждение вызывает его сбой.Кроме того, когда ваша логика настройки выдает ошибку и приводит к сбою ваших тестов, вывод консоли скажет, что произошел сбой в блоке before.

...