angular Jasmine - 不能设置undefined的属性

时间:2017-10-10 21:48:24

标签: angular jasmine karma-jasmine

我的组件代码:

public save() {
  this.gridService.gridCellUpdated = false;
}

我的Jasmine代码

class GridServiceMock {
  public gridCellUpdated = false;
}
let gridService: GridService;
beforeEach(
  async(() => {
    TestBed.configureTestingModule({
      declarations: [ModalComponent, BsModalDirective],
      providers: [{ provide: GridService, use: GridServiceMock }]
    })
    .compileComponents();
  });
);

it('should save assets', () => {
  gridService = fixture.debugElement.injector.get(GridService);
  component.save();
  expect(gridService.gridCellUpdated).toBeFalsy();
});

我的错误:

TypeError: Cannot set property 'gridCellUpdated' of undefined

编辑: 通过以下解决方案更新了代码,但仍然得到相同的错误。

2 个答案:

答案 0 :(得分:2)

正如@Vega在评论中提到的:该服务不是该组件的属性。它将被注入。

您对测试模块的设置是正确的,您可以从Testbed获得这样的服务:

app.on('error', cb)

它将GridService的一个实例作为GridServiceMock。你的测试现在应该成功。

此致

答案 1 :(得分:2)

我不确定您为什么要使用provideuseClass来提供此服务。当您必须自己创建服务的自定义/轻量级实现时(例如,当您将Angular' RouterActivatedRoute注入时,通常会执行此操作依赖于你的控制器。)

对于当前场景,您只需要引用已创建的服务的注入依赖项。

所以你可以简单地使用providers数组将它提供给你的测试模块,如下所示:

beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [ ModalComponent ],
    providers: [ GridService ]
  })
  .compileComponents();
}));

然后,您可以使用GridService获取对fixture.debugElement.injector.get(GridService);的引用,并像这样测试您的save方法:

describe('save', () => {

  it('should set gridCellUpdated on GridService to false', () => {

    let gridService = fixture.debugElement.injector.get(GridService);
    expect(gridService.gridCellUpdated).toBeTruthy();

    component.save();

    expect(gridService.gridCellUpdated).toBeFalsy();

  });

});

<强>更新 如果您仍需使用provide方式提供服务,请使用useClass代替use。像这样:

beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [ ModalComponent ],
    providers: [ { provide: GridService, useClass: GridServiceMock } ]
  })
  .compileComponents();
}));

以与讲述相同的方式编写测试。它应该工作。

<强>更新 这是整个测试文件,仅供参考:

&#13;
&#13;
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { GridService } from './../../services/grid.service';
import { ModalComponent } from './modal.component';

class GridServiceMock {
  public gridCellUpdated = false;
}

describe('ModalComponent', () => {
  let component: ModalComponent;
  let fixture: ComponentFixture<ModalComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ ModalComponent ],
      providers: [ { provide: GridService, useClass: GridServiceMock } ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ModalComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should be created', () => {
    expect(component).toBeTruthy();
  });

  describe('save', () => {

    it('should set gridCellUpdated on GridService to false', () => {

      let gridService = fixture.debugElement.injector.get(GridService);
      expect(gridService.gridCellUpdated).toBeTruthy();

      component.save();

      expect(gridService.gridCellUpdated).toBeFalsy();

    });

  });

});
&#13;
&#13;
&#13;

测试正在通过:

Passing Tests

希望有所帮助!