首页 > 解决方案 > 使用 Jasmine 的未定义依赖项

问题描述

我想测试这段代码:

   constructor(drawingService: DrawingService) {
       super(drawingService);
       //...
    }

   private writeOnCanvas(): void {
      this.drawingService.clearCanvas(this.drawingService.previewCtx);

      this.drawingService.baseCtx.fillStyle = 'red';
      this.drawingService.baseCtx.font = 'arial 20px';
      this.drawingService.baseCtx.textAlign = 'center';

      this.drawingService.baseCtx.fillText("hello",0, 0);
}

这是绘图服务:

export class DrawingService {
   baseCtx: CanvasRenderingContext2D;
   previewCtx: CanvasRenderingContext2D;
   cursorCtx: CanvasRenderingContext2D;
   canvas: HTMLCanvasElement;
   previewCanvas: HTMLCanvasElement;

   clearCanvas(context: CanvasRenderingContext2D): void {
       //do something
   }

这是我的 .spec 文件:

fdescribe('TextService', () => {
  let service: TextService;
  let drawingServiceSpy: jasmine.SpyObj<DrawingService>;
  // const drawingServiceMock = {
  //   clearCanvas: jasmine.createSpy('clearCanvas'),
  //   baseCtx : CanvasRenderingContext2D,

beforeEach(() => {
  TestBed.configureTestingModule({
    providers: [ 
       { provide: DrawingService, useValue: drawingServiceSpy },
    ]
  });
  drawingServiceSpy = jasmine.createSpyObj('DrawingService',['clearCanvas']);
  service = TestBed.inject(TextService);
});


it('shoud write on baseCtx', () => {
  const ctx = CanvasType.baseCtx;
  service['drawingService'].baseCtx.fillStyle = 'red';
  service['drawingService'].baseCtx.font = 'Bold 10px Arial';
  service['drawingService'].baseCtx.textAlign = 'center' as CanvasTextAlign;

  service['writeOnCanvas'](ctx);

  expect(drawingServiceSpy.clearCanvas).toHaveBeenCalled();
  expect(drawingServiceSpy.baseCtx.fillText).toHaveBeenCalled();
});

我明白了

Cannot set property 'fillStyle' of undefined' error.

我认为问题来自

{
  provide: DrawingService,
  useValue: drawingServiceSpy
}

我尝试使用 mockClass 但出现错误...

标签: angulartypescriptunit-testingjasmine

解决方案


您的订单似乎已取消。

尝试这个:

beforeEach(() => {
  // put this line first so then it can be provided in the useValue properly
  drawingServiceSpy = jasmine.createSpyObj('DrawingService',['clearCanvas']);
  TestBed.configureTestingModule({
    providers: [ 
       { provide: DrawingService, useValue: drawingServiceSpy },
    ]
  });
  service = TestBed.inject(TextService);
});

然后对于测试,baseCtx在继续之前先设置一个空对象。

it('shoud write on baseCtx', () => {
  // first set baseCtx to an empty object before setting properties in it
  service['drawingService'].baseCtx = {};
  service['drawingService'].baseCtx.fillStyle = 'red';
  service['drawingService'].baseCtx.font = 'Bold 10px Arial';
  service['drawingService'].baseCtx.textAlign = 'center' as CanvasTextAlign;

  service['writeOnCanvas'](ctx);

  expect(drawingServiceSpy.clearCanvas).toHaveBeenCalled();
  expect(drawingServiceSpy.baseCtx.fillText).toHaveBeenCalled();
});

推荐阅读