如何在Jasmine中测试依赖于私有参数的方法

时间:2019-09-11 20:35:02

标签: angular unit-testing jasmine

我根本没有编辑组件文件的权限,因此这不是一个选择。我必须测试一种依靠私有变量才能成功运行的方法。

  candidateSmartMatch(): void {
    const jobAddressFormGroup = this.locationModel.formGroup.get('JobAddress');
    if (!!jobAddressFormGroup) {
      this.subs.sink = jobAddressFormGroup.valueChanges.pipe(
        debounceTime(2000),
        filter((value: PostLocationInterface) => !!value.CityState || !!value.Zip)
      ).subscribe(
        (value: PostLocationInterface) => {
          const formattedAddress = this.formatAddress({
            StreetAddress1: value.StreetAddress1,
            StreetAddress2: value.StreetAddress2,
            CityState: value.CityState,
            Zip: value.Zip,
            DispCity: ''
          });
          this.candidateSmartMatchManagementService.setJobLocation(formattedAddress);
          this.jobCompetitionService.setLocation(formattedAddress);
        });
    }
  }

变量this.locationModel来自构造函数,在此将其作为私有参数输入。有一个initialize()方法可以像这样设置公共变量form

this.form = this.locationModel.formGroup;

如果我可以在单元测试中获得this.form的值,那也许可以解决我的问题,但是调用component.initialize()似乎没有什么不同。我还尝试在测试中创建模拟表单。这是我的测试:

  it('call setJobLocation method', fakeAsync(() => {
    spyOn(candidateSmartMatchManagementService, 'setJobLocation');
    component.initialize();
    component.form = new FormGroup({
      StreetAddress1: new FormControl('Street1'),
      StreetAddress2: new FormControl('Street2'),
      CityState: new FormControl('Miami, FL'),
      Zip: new FormControl('33015'),
      FormattedAddress: new FormControl('Street1 Street2 Miami, FL 33015')
    });
    component.candidateSmartMatch();
    expect(candidateSmartMatchManagementService.setJobLocation).toHaveBeenCalled();
  }));

基本上,我只是尝试测试一种情况,其中方法candidateSmartMatch成功调用方法setJobLocation。我正在为candidateSmartMatchManagementService使用模拟服务,但其中包含setJobLocation的模拟方法。

编辑:

我按照建议的方法更改了测试方法,以使用locationModel模拟,但仍然说“预期的间谍setJobLocation已被调用”

  it('call setJobLocation method', fakeAsync(() => {
    spyOn(candidateSmartMatchManagementService, 'setJobLocation');
    jobLocationModel.formGroup = new FormGroup({
      StreetAddress1: new FormControl('Street1'),
      StreetAddress2: new FormControl('Street2'),
      CityState: new FormControl('Miami, FL'),
      Zip: new FormControl('33015'),
      FormattedAddress: new FormControl('Street1 Street2 Miami, FL 33015')
    });
    component.candidateSmartMatch();
    expect(candidateSmartMatchManagementService.setJobLocation).toHaveBeenCalled();
  }));

这是我的模型模型:

export class JobLocationModelMock {
  formGroup = new FormGroup({
    JobAddressID: new FormControl('test'),
    JobRelocation: new FormControl(),
    FormattedAddress: new FormControl(),
    JobAddress : new FormGroup({
      JobRelocation: new FormControl(),
      CityState: new FormControl(),
      Zip: new FormControl(),
      StreetAddress1: new FormControl('test'),
      StreetAddress2: new FormControl(),
      DispCity: new FormControl()
    }),
    JobAddresses: new FormArray([])
  });
  private model: PostJobService = new PostJobService();
  init(): Observable<any> { return Observable.of([]); }

  defineModel() {
    return;
  }
}

1 个答案:

答案 0 :(得分:0)

如果我对您的理解正确,那么您正在通过当前组件的构造函数发送locationModel。如果是这种情况,那么您可以在建立TestBed的过程中传递模拟模型。在没有看到您的设置代码的情况下,我将举个例子。

beforeEach(async(() => {
    TestBed.configureTestingModule({
      providers: [
        {
          provide: LocationModel, useValue: MockLocationModel
        }
      ],
      declarations: [Component]
    })
      .compileComponents();
  }));

就可以进行测试而言,好像您有一个侦听器正在检查表单中的值更改。在某些时候,您只需要在测试中调用component.candidateSmartMatch();后就可以设置/更新表单中的某些值。