【问题标题】:angular Jasmine - cannot set property of undefined角茉莉花 - 无法设置未定义的属性
【发布时间】:2017-10-10 21:48:23
【问题描述】:

我的组件代码:

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

我的茉莉花代码

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

编辑: 按照以下解决方案更新了代码,但仍然出现相同的错误。

【问题讨论】:

  • 投反对票的原因是什么?
  • 我不确定,但我不同意他们的观点,所以我将 null 说出来......
  • 你试过将它注入你的测试吗? inject([GridService], (gridService: GridService) ?
  • 我认为这与 gridService 不是组件属性有关。

标签: angular jasmine karma-jasmine


【解决方案1】:

我不知道您为什么在这里使用provideuseClass 来提供这项服务。这通常在您必须自己创建服务的自定义/轻量级实现时完成(例如,当您将 Angular 的 RouterActivatedRoute 作为对控制器的依赖项注入时)。

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

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

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

然后您可以使用fixture.debugElement.injector.get(GridService); 获得对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();
}));

并按照告知的方式编写测试。它应该可以工作。

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

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();

    });

  });

});

测试通过了:

希望有帮助!

【讨论】:

  • 也按照这种方式,但错误仍然存​​在。
  • 在您的问题中,您指的是通过您的控制器 (component.gridService.gridCellUpdated) 提供的服务。你更新了吗?你应该再检查一次。可能还缺少什么。
  • 请检查我的新代码。我按照解决方案进行了更新。
  • 您仍在使用providers: [{ provide: GridService, use: GridServiceMock }] 提供服务。我已指定不这样做。
  • 没有任何方法可以使用模拟服务吗?这就是我被要求做的事情
【解决方案2】:

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

您的测试模块设置正确,您可以像这样从测试平台获取服务:

let gridService: GridService;
let fixture: ComponentFixture<ModalComponent>;
let component: ModalComponent;

TestBed.configureTestingModule({...});

TestBed.compileComponents().then(() => {
  fixture = TestBed.createComponent( ModalComponent ); 
  component = fixture.debugElement.componentInstance;
  gridService= fixture.debugElement.injector.get( GridService );
} );

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

问候

【讨论】:

  • 按照你说的做了。但我得到了同样的错误。
【解决方案3】:

花了 15 分钟试图找出为什么会发生这种情况,结果发现我错过了声明 it() 块并直接在 describe() 块中编写我的测试用例语句。确保您的语句在 it() 块内。

【讨论】:

    猜你喜欢
    • 2018-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 2019-04-06
    • 2021-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多