我应该在测试用例中使用try-catch吗?

时间:2018-10-19 08:10:54

标签: unit-testing jasmine mocha jestjs

我在想一个问题。这是一个示例:

index.ts

async function getUserById(id?: number) {
  return new Promise((resolve, reject) => {
    if (id) {
      const user = { id };
      resolve(user);
    } else {
      reject(new Error('user id is required'));
    }
  });
}

export { getUserById };

index.spec.ts

import { getUserById } from './';

const coin = () => Math.random() > 0.5;

describe('should throw an error test suites', () => {
  const testCount = 1000;

  for (let i = 0; i < testCount; i++) {
    it(`t-${i}`, async () => {
      const id = coin() ? 1 : 0;
      try {
        const user = await getUserById(id);
        expect(user).toEqual({ id });
      } catch (error) {
        expect(error.message).toBe('user id is required');
      }
    });
  }
});

测试结果:

Test Suites: 1 passed, 1 total
Tests:       1000 passed, 1000 total
Snapshots:   0 total
Time:        2.637s

如您所见,我动态生成了很多测试用例。问题是在这种情况下测试用例将始终通过。我认为同时测试correct部分和exception部分是不正确的。我说得对吗?

在测试用例中什么时候应该使用try-catch

谢谢。

2 个答案:

答案 0 :(得分:0)

如果要测试应用程序是否在给定的时间引发了预期的异常,则应使用try-catch块触发异常并对其进行评估。

我认为您不能说除此之外还有什么规则集可以使用。当然,这取决于您的目标和您的编码风格,但是随后我们正在寻求基于意见的答案,对于该网站而言,这是有点题外话了;-)

答案 1 :(得分:0)

在测试代码中使用try-catch本身不是问题。实际上,如果您想在测试代码中验证被测系统(SUT)是否按预期抛出期望,则甚至需要这样做。

但是,您的特定示例在测试代码中做了某些不利后果。一件事是您的测试代码将两个不同方面(成功方案和失败方案)的测试合并到一个测试函数中。缺点之一是,这会使测试代码复杂化,并有时使您难以理解设置的哪个部分对于哪个测试是必需的。您使用try-catch合并测试,但不是try-catch是问题,而是合并。

实际上,这种合并实际上使您陷入陷阱:合并的测试无法正常工作。例如,您随机选择一个idid为1应该导致正确的user被传递。但是,您并没有真正测试:如果您的SUT错误地总是抛出异常,您将认为这是成功的测试。

第二,您运行了1000个测试,但实际上仅测试了两个方案(方面)。因此,这1000个测试不会给您带来任何好处。恰恰相反:过于复杂甚至可能意味着您错误地(由于选择方案而导致的错误)不测试两个方案。或者,碰巧总是选择了一种情况(不太可能被接受)。无论如何,您浪费时间来执行1000个测试,而仅测试两个方面的有效值。