【问题标题】:Is Angular component unit testing actually unit testing?Angular 组件单元测试实际上是单元测试吗?
【发布时间】:2019-07-11 08:37:25
【问题描述】:

我开始学习单元测试,并了解主要目标是单独测试系统。因此,任何依赖项都应该被存根、模拟等。

根据有关测试的 Angular 文档,您应该模拟通过依赖注入提供的任何内容。到现在为止还挺好。但是,如下代码所示,您可以通过共享或功能模块简单地导入其他所需的模块、组件、指令、管道。

那么这真的是单元测试吗?如果被测目标系统是一个组件,这不是在测试它的整个模块吗?

或者这只是一种让步,在现实世界的应用程序中模拟所有需求几乎是不可能的?

beforeEach(async(() => {
  const routerSpy = createRouterSpy();

  TestBed.configureTestingModule({
    imports:      [ SharedModule ],
    declarations: [ HeroDetailComponent ],
    providers: [
      { provide: ActivatedRoute, useValue: activatedRoute },
      { provide: HeroService,    useClass: TestHeroService },
      { provide: Router,         useValue: routerSpy},
    ]
  })
  .compileComponents();
}));

【问题讨论】:

    标签: angular unit-testing jasmine


    【解决方案1】:

    那么这真的是单元测试吗?如果被测目标系统是一个组件,这不是在测试它的整个模块吗?

    单元测试的定义是测试源代码的小单元,组件其实就是源代码的小单元。

    但是,如下代码所示,您可以通过共享或功能模块简单地导入其他所需的模块、组件、指令、管道。

    可以在 JavaScript 中测试最小源代码单元是pure function。如果你是一个最纯粹的人,那么任何 更大 都不再是 smallest 单元,但 Angular 是一个 Object Oriented 框架,所以在这种范式下,我们可以说一个 >object最小的 单位。所以像组件、服务、激活器、解析器这些都是对象的东西都可以被单元测试覆盖。

    或者这只是一种让步,在现实世界的应用程序中模拟所有需求几乎是不可能的?

    祝你在构建系统后尝试测试它。

    如果您想构建可以测试的东西,请先编写测试。

    https://en.wikipedia.org/wiki/Test-driven_development

    纯组件

    纯组件是没有外部依赖关系的组件,不会改变外部状态,并且会为相同的输入生成相等的输出。具有用户表单的组件不可能像new Date() 不纯一样

    单元测试框架了解这些现实世界问题,并提供模拟、间谍等解决方案,以允许测试人员通过测试来覆盖不纯的源代码,以验证纯环境中的期望 可重复的方式。

    这就是你所能做的,但它仍然是单元测试,这才是最重要的。

    【讨论】:

      【解决方案2】:

      你写

      主要目标是单独测试系统

      是的 - 也不是。单元测试用于发现可以在隔离软件中找到的错误。这并不意味着您实际上必须在测试期间隔离代码。换句话说,您不必模拟所有依赖项。例如,如果您的代码使用sin() 函数,这也是对不同代码部分的依赖,但这种依赖通常不会损害您正确测试代码的能力。

      一般规则是,嘲笑应该是有原因的。充分的理由是:

      • 您无法轻松地使依赖组件 (DOC) 的行为符合您的测试预期。
      • 调用 DOC 是否会导致任何非确定性行为(日期/时间、随机性、网络连接)?
      • 测试设置过于复杂和/或维护密集(例如,需要外部文件)
      • 原始 DOC 为您的测试代码带来了可移植性问题。
      • 使用原始 DOC 是否会导致构建/执行时间过长而无法接受?
      • 是否存在导致测试不可靠的 DOC 稳定性(成熟度)问题,或者更糟糕的是,DOC 甚至还没有可用?

      如您所见,sin() 函数的使用通常不属于上述原因。您必须判断这是否也适用于您的场景。

      但是,上述观点的一个结论是,如果您不模拟所有依赖项,您也可以进行单元测试。但是 - 那么单元测试的区别属性是什么?单元测试与例如集成测试的区别在于您在各自测试中追求的目标。

      如果您的目标是在处理另一个组件的方式中发现错误(例如,如果以错误的顺序或使用错误的参数调用其他组件的函数,或者如果返回值不是预期的形式等) ,那么这将不是单元测试,而是集成测试:在单独测试您的组件时,您甚至无法找到这些错误 - 您需要其他组件来找到它们。

      【讨论】:

        【解决方案3】:

        (严重基于意见,因此请随意不同意)这并不是真正特定于 Angular,例如,如果您正在对使用 numpy 的 Python 函数进行单元测试,您仍然会在 UT 中导入 numpy。所以在这里你可以导入材料组件作为例子,你不能真正模拟它们(即使你可以,这也不是一个好主意,你要确保你正确使用它们)。 基本上我会说在单元测试中你正在模拟/存根 your 其他功能(这里的 heroService 是模拟的)和 http 请求响应,但你只能假设外部库按预期工作,所以你仍然导入和使用它们.

        【讨论】:

          猜你喜欢
          • 2021-01-05
          • 2019-11-03
          • 2017-10-10
          • 1970-01-01
          • 2014-06-03
          • 2019-03-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多