【问题标题】:Testing private methods in JestJS在 JestJS 中测试私有方法
【发布时间】:2019-08-04 11:47:34
【问题描述】:

我正在使用 NestJS(使用 TypeScript)制作一个 API,它使用 JestJS 作为默认测试框架。我正在为服务类编写测试,并尝试访问其私有函数(使用 TypeScript 强制执行),但由于明显的原因我不能。

其他语言(如 Java)的传统解决方案是将函数更改为 package 或 internal 范围内,但这在 TypeScript 中不存在。

我怎样才能访问这些功能以进行测试,但仍强制执行私有访问(作为良好做法)?

【问题讨论】:

  • 一种解决方案是使用括号访问私有属性,即obj['privateMethod']() 但是,私有方法必须由公共方法调用,而这正是您应该测试/调用的。
  • 我正在测试公共的,但我想确保私有函数中的简单 i/o 算法正常工作。感谢您的建议。

标签: typescript unit-testing jestjs private-members nestjs


【解决方案1】:

作为准则,您应该能够使用其公共方法来测试一个类。如果私有/受保护访问中隐藏着重要的功能,那么这可能是一个信号,表明它可以被重构到另一个类中。

您是否可以将复杂的私有方法重构为另一个可以单独测试的类?

请记住,测试你的私有方法会使你的测试更容易受到你实现类行为方式的改变的影响,即使类本身的行为没有改变。例如,在重构优化时很可能会出现这种情况。

编辑: 鉴于您在基础级别使用 JavaScript,有几种方法可以实现您的目标,例如您发布的解决方案使方法受到保护并使用子类进行测试,或者通过使方法公开的一些变体,暂时的或永久的,但以任何形式这样做几乎肯定是不明智的。我强烈建议阅读以下链接,该链接提供了有关为什么这样做是一个坏主意的更多信息,并且还为您遇到的问题提供了潜在的良好解决方案: https://enterprisecraftsmanship.com/2017/10/23/unit-testing-private-methods/

【讨论】:

  • 我不确定这个问题是否有非主观的答案,但我不同意这个答案应该是评论的想法(它试图回答这个问题,而不是进一步)
  • 这可能是真的,但在我的情况下,这些操作永远不会在服务类(我想测试的那个)之外使用,所以创建另一个类不是一个好主意,但我看看你的意思。另外,我不会做环境切换,因为我看到的例子太乱了。我会发布一个我正在使用的好解决方案。
  • 这里除了许多好的建议外,还有一个逻辑缺陷。将私有内容更改为公共内容肯定会改变其可访问性。但是,如果在测试私有的东西时测试很脆弱,为什么只有将同样的私有东西公开,它们就不再脆弱了?
  • @dirkhermann 我无意暗示这样做是个好主意。我已经用一个描述反模式的链接替换了这部分,并提供了一些好的解决方案。谢谢!
  • 我接受了这个答案,因为它是更好的解决方案。但我还在下面提供了一个对大多数人都有效的直接答案。有时你在一家公司工作,你的经理要求你做某事,你就照做了,即使这是不好的做法。我不想争论,我只想完成它,我相信其他人也这样做。谢谢。
【解决方案2】:

我的解决方案是使函数“受保护”,并在测试文件内的一个类中扩展该类,并暴露这些函数。

例子:

class ClassToTest {
    protected add(x: number, y: number}: number {
        return x + y;
    }
}

在测试文件中:

class PublicClassToTest extends ClassToTest {
    public add(x: number, y: number): number {
        return super.add(x, y);
    }
}

describe('ClassToTest', () => {

    const obj = new PublicClassToTest();

    it('adding 2 numbers', () => {
        // GIVEN x is 6
        const x = 6;

        // AND y is 2
        const y = 2;

        // WHEN we add them
        const result = obj.add(x, y);

        // THEN the result is 8
        expect(result).toBe(8);
    });
});

作为奖励功能:这不仅解决了我的问题,而且还为我提供了一种从测试文件中查看函数头的好方法,而无需来回切换在我的测试和我正在测试的课程之间。

【讨论】:

  • TypeScript 不允许您在子类中扩展私有方法并将其公开
  • 我的错!我忘了说我使功能“受保护”。我更新了我的答案。感谢您的关注:)
  • 问题是当有人查看这个类时,他们会认为这个方法是打算被覆盖的,而实际上并非如此。我会改为遵循其他建议。当某些东西不容易测试时,通常表明它可以使用一些重构
  • 我同意这不是完美的解决方案,而另一个更好,但我想为人们提供一个适用于大多数情况的选项,比如我的。但是,总的来说,我建议在另一个答案中使用该解决方案。我会接受那个而不是我的。
猜你喜欢
  • 1970-01-01
  • 2019-02-01
  • 2020-11-08
  • 1970-01-01
  • 2019-01-23
  • 1970-01-01
  • 2017-06-06
  • 1970-01-01
相关资源
最近更新 更多