代码审查:这是抛出异常的单元测试的一种干净方法吗?

时间:2018-09-11 02:40:32

标签: javascript unit-testing jasmine sinon

这里有人可以评论上述测试用例的质量吗?我在这里测试是否应该抛出异常。我的意思是它可以工作,但这是对应该引发异常的方案进行单元测试的正确方法。

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 :(得分:1)

我个人不喜欢必须写多个失败条款。我认为这使测试更难阅读。另外,我会调整您的测试结构。

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块中说失败。

答案 1 :(得分:1)

使函数异步意味着它将返回promise,而不是立即值。

因此,在chai-as-promised的帮助下,您可以执行以下操作:

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

在我看来,这种方式实际上还可以检查本地JSON.parse是否运行良好,而不是测试自己的代码。

答案 2 :(得分:1)

我也想添加自己的答案:)我最终按照这里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();
    });
  });
});