Unable to test my code because of the following error: this.instructionsService.instruction.subscribe is not a function , please see the code below:

huangapple go评论108阅读模式
英文:

Unable to test my code because of the following error: this.instructionsService.instruction.subscribe is not a function , please see the code below:

问题

以下是翻译好的部分:

  1. instruction-context.component.spec.ts
  2. let instructionService: InstructionsService;
  3. let mockInstructionService: = {
  4. instruction: new BehaviorSubject<any>({}).asObservable(),
  5. applyInstruction: () => {},
  6. };
  7. let expectedInstructions = {[]}// object with some expected data
  8. beforeEach(
  9. waitForAsync(() => {
  10. TestBed.configureTestingModule({
  11. declarations: [InstructionContextComponent],
  12. imports: [HttpClientTestingModule],
  13. providers: [
  14. { provide: InstructionsService, useValue: mockInstructionService},
  15. HttpService
  16. ]
  17. }).compileComponents();
  18. })
  19. );
  20. beforeEach(() => {
  21. fixture = TestBed.createComponent(InstructionContextComponent);
  22. instructionService = TestBed.inject(InstructionsService);
  23. component = fixture.componentInstance;
  24. fixture.detectChanges();
  25. });
  26. describe('ngOninit', () => {
  27. let instrcutionServiceSpyApplyInstruction;
  28. beforeEach(() => {
  29. instrcutionServiceSpyApplyInstruction = spyOn(instructionService, 'applyInstruction');
  30. spyOn(instructionService , 'instruction' as any).and.returnValue(of(expectedInstructions));
  31. });
  32. it('should create', () => {
  33. // 断言
  34. expect(component).toBeTruthy();
  35. });
  36. it('should apply correct state when mode is "create" and locationData is present',
  37. fakeAsync(() => {
  38. // 准备
  39. component.mode = 'create';
  40. component['locationData'] = [{ id: '1', name: 'Node 1' }] as any;
  41. // 执行
  42. component.ngOnInit();
  43. tick(100);
  44. // 断言
  45. expect(clearInterval).toHaveBeenCalled();
  46. expect(instrcutionServiceSpyApplyInstruction ).toHaveBeenCalled();
  47. }));
  48. })
  49. instructionService.ts
  50. public instruction: BehaviorSubject<Instructions>;
  51. set instructions(){
  52. let state
  53. // 设置一些状态值
  54. this.instruction.next({
  55. ...state
  56. });
  57. }
  58. instruction-context.component.ts
  59. ngOninit(){
  60. this.instructionsService.instruction.subscribe((instruction: IInstruction) => {
  61. this.instruction = instruction;
  62. this.instructionLevel = this.instruction && this.instruction['level'];
  63. this.instructionContext = this.instruction && this.instruction['context'];
  64. if (this.instructionContext) {
  65. this.locationData = this.instructionContext['locationData'];
  66. if (this.instructionContext['types'] && this.instructionContext['types'][this.mode]) {
  67. this.filterNodes = this.instructionContext['types'][this.mode][
  68. 'filterNodes'
  69. ];
  70. this.tree = this.instructionContext['types'][this.mode]['treeData'];
  71. this.selectedDevicesCount = Array.isArray(
  72. this.instructionContext['types'][this.mode]['selectedNodes']
  73. )
  74. ? this.instructionContext['types'][this.mode]['selectedNodes'].length
  75. : 0;
  76. }
  77. }
  78. this.validity.emit(this.checkFormValidity());
  79. });

希望这能帮助到您。如果您需要任何进一步的帮助,请告诉我。

英文:

instruction-context.component.spec.ts

  1. let instructionService: InstructionsService;
  2. let mockInstructionService: = {
  3. instruction: new BehaviorSubject<any>({}).asObservable(),
  4. applyInstruction: () => {},
  5. };
  6. let expectedInstructions = {[]}// object with some expected data
  7. beforeEach(
  8. waitForAsync(() => {
  9. TestBed.configureTestingModule({
  10. declarations: [InstructionContextComponent],
  11. imports: [HttpClientTestingModule],
  12. providers: [
  13. { provide: InstructionsService, useValue: mockInstructionService},
  14. HttpService
  15. ]
  16. }).compileComponents();
  17. })
  18. );
  19. beforeEach(() => {
  20. fixture = TestBed.createComponent(InstructionContextComponent);
  21. instructionService = TestBed.inject(InstructionsService);
  22. component = fixture.componentInstance;
  23. fixture.detectChanges();
  24. });
  25. describe('ngOninit', () => {
  26. let instrcutionServiceSpyApplyInstruction;
  27. beforeEach(() => {
  28. instrcutionServiceSpyApplyInstruction = spyOn(instructionService, 'applyInstruction');
  29. spyOn(instructionService , 'instruction' as any).and.returnValue(of(expectedInstructions));
  30. });
  31. it('should create', () => {
  32. //Assert
  33. expect(component).toBeTruthy();
  34. });
  35. it('should apply correct state when mode is "create" and locationData is present',
  36. fakeAsync(() => {
  37. // Arrange
  38. component.mode = 'create';
  39. component['locationData'] = [{ id: '1', name: 'Node 1' }] as any;
  40. // Act
  41. component.ngOnInit();
  42. tick(100);
  43. // Assert
  44. expect(clearInterval).toHaveBeenCalled();
  45. expect(instrcutionServiceSpyApplyInstruction ).toHaveBeenCalled();
  46. }));
  47. })

instructionService.ts

  1. public instruction: BehaviorSubject<Instructions>;
  2. set instructions(){
  3. let state
  4. //setting some values for state
  5. this.instruction.next({
  6. ...state
  7. });
  8. }

instruction-context.component.ts

  1. ngOninit(){
  2. this.instructionsService.instruction.subscribe((instruction: IInstruction) => {
  3. this.instruction = instruction;
  4. this.instructionLevel = this.instruction && this.instruction['level'];
  5. this.instructionContext = this.instruction && this.instruction['context'];
  6. if (this.instructionContext) {
  7. this.locationData = this.instructionContext['locationData'];
  8. if (this.instructionContext['types'] && this.instructionContext['types'][this.mode]) {
  9. this.filterNodes = this.instructionContext['types'][this.mode][
  10. 'filterNodes'
  11. ];
  12. this.tree = this.instructionContext['types'][this.mode]['treeData'];
  13. this.selectedDevicesCount = Array.isArray(
  14. this.instructionContext['types'][this.mode]['selectedNodes']
  15. )
  16. ? this.instructionContext['types'][this.mode]['selectedNodes'].length
  17. : 0;
  18. }
  19. }
  20. this.validity.emit(this.checkFormValidity());
  21. });

The line I get the error is at this.instructionsService.instruction.subscribe, the first line in my ngOninit() method, in my component and component.ngOnInit() in the spec file. As can be seen in the code 'instruction' is an observable. As per my knowledge ,I have mocked the required dependencies correctly. Not sure what am I missing here. Any help would be highly appreciated!

答案1

得分: 1

尝试删除beforeEach中的第二行,看看是否有效。我们只能在方法/函数上使用spyOn,不能用于实例变量如instruction

其余部分我觉得没问题。

  1. beforeEach(() => {
  2. instrcutionServiceSpyApplyInstruction = spyOn(instructionService, 'applyInstruction');
  3. // !! 删除这一行
  4. spyOn(instructionService, 'instruction' as any).and.returnValue(of(expectedInstructions));
  5. });
英文:

Try getting rid of the second line in the beforeEach to see if it works. We can only use spyOn for methods/functions, not instance variables like instruction.

The rest looks ok to me.

  1. beforeEach(() => {
  2. instrcutionServiceSpyApplyInstruction = spyOn(instructionService, 'applyInstruction');
  3. // !! Get rid of this line
  4. spyOn(instructionService , 'instruction' as any).and.returnValue(of(expectedInstructions));
  5. });

huangapple
  • 本文由 发表于 2023年7月24日 19:23:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76753983.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定