Angular 小吃店服务茉莉花测试

Posted

技术标签:

【中文标题】Angular 小吃店服务茉莉花测试【英文标题】:Angular snackbar service jasmine testing 【发布时间】:2020-06-30 15:29:33 【问题描述】:

我想用 jasmine 测试小吃店服务。更具体地说,我正在测试以下两种情况:

    服务已创建 里面要调用的方法

snackbar.service

import  Injectable, NgZone  from '@angular/core';
import  MatSnackBar  from '@angular/material';

@Injectable(
  providedIn: 'root'
)
export class SnackbarService 

  constructor(
    public snackBar: MatSnackBar,
    private zone: NgZone
  )  

  public open(message, action, duration = 1000) 
    this.zone.run(() => 
      this.snackBar.open(message, action,  duration );
    )
  

snackbar.service.spec

import  TestBed  from '@angular/core/testing';
import  SnackbarService  from './snackbar.service';

describe('SnackbarService', () => 
  beforeEach(() => TestBed.configureTestingModule());

  it('should be created', () => 
    const service: SnackbarService = TestBed.get(SnackbarService);
    expect(service).toBeTruthy();
  );

  it('should call open()', () => 
    const service: SnackbarService = TestBed.get(SnackbarService);
    const spy = spyOn(service, 'open');
    service.open('Hello', 'X', 1000);
    expect(spy).toHaveBeenCalled();
  )
);

运行测试后,Karma 给我以下错误:

    SnackbarService > 应该调用 open() NullInjectorError:StaticInjectorError(DynamicTestModule)[MatSnackBar]: StaticInjectorError(平台:核心)[MatSnackBar]: NullInjectorError:没有 MatSnackBar 的提供者! SnackbarService > 应该被创建 NullInjectorError:StaticInjectorError(DynamicTestModule)[MatSnackBar]: StaticInjectorError(平台:核心)[MatSnackBar]: NullInjectorError:没有 MatSnackBar 的提供者!

关于我应该如何解决这个问题的任何想法?

谢谢!

【问题讨论】:

【参考方案1】:

是的,您必须导入并提供所需的内容。

import  TestBed  from '@angular/core/testing';
import  SnackbarService  from './snackbar.service';
import  MatSnackBarModule  from '@angular/material/snack-bar';

describe('SnackbarService', () => 
  let zone: NgZone;
  let snackBar: MatSnackBar;
  beforeEach(() => TestBed.configureTestingModule(
     imports: [MatSnackBarModule],
     providers: [
       SnackbarService,
       NgZone,
     ],
  ));

  beforeEach(() => 
    // if you're on Angular 9, .get should be .inject
    zone = TestBed.get(NgZone);
    spyOn(zone, 'run').and.callFake((fn: Function) => fn());
    snackBar = TestBed.get(MatSnackBar);
  );

  it('should be created', () => 
    const service: SnackbarService = TestBed.get(SnackbarService);
    expect(service).toBeTruthy();
  );

  // the way you have written this test, it asserts nothing
  it('should call open()', () => 
    const service: SnackbarService = TestBed.get(SnackbarService);
    // const spy = spyOn(service, 'open');
    const spy = spyOn(snackBar, 'open');
    service.open('Hello', 'X', 1000);
    expect(spy).toHaveBeenCalled();
  )
);

我从未对需要 NgZone 的东西进行单元测试,但如果遇到问题 (Running jasmine tests for a component with NgZone dependency),请查看此内容。

【讨论】:

感谢您的帮助!我照你说的做了,又跑了一次测试。弹出此错误:错误:无法解析 NgZone 的所有参数:(?)。然后我尝试使用您共享的链接修复它。不幸的是,没有运气。 设法修复它!我从我的服务中删除了 ngZone,无需再担心了。

以上是关于Angular 小吃店服务茉莉花测试的主要内容,如果未能解决你的问题,请参考以下文章

如何在茉莉花中为可观察的 finally 块编写单元测试 - Angular 2

在业力旁边使用玩笑的冲突类型,Angular 上的茉莉花

Angular 2 业力设置问题——业力启动但不运行测试

使用 Jasmine 进行 Angular 单元测试:如何删除或修改 spyOn

将角种子茉莉花单元测试转换为咖啡脚本

如何用茉莉弹珠测试对象