instruction-context.component.spec.ts
let instructionService: InstructionsService;
let mockInstructionService: = {
instruction: new BehaviorSubject<any>({}).asObservable(),
applyInstruction: () => {},
};
let expectedInstructions = {[]}// object with some expected data
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [InstructionContextComponent],
imports: [HttpClientTestingModule],
providers: [
{ provide: InstructionsService, useValue: mockInstructionService},
HttpService
]
}).compileComponents();
})
);
beforeEach(() => {
fixture = TestBed.createComponent(InstructionContextComponent);
instructionService = TestBed.inject(InstructionsService);
component = fixture.componentInstance;
fixture.detectChanges();
});
describe('ngOninit', () => {
let instrcutionServiceSpyApplyInstruction;
beforeEach(() => {
instrcutionServiceSpyApplyInstruction = spyOn(instructionService, 'applyInstruction');
spyOn(instructionService , 'instruction' as any).and.returnValue(of(expectedInstructions));
});
it('should create', () => {
//Assert
expect(component).toBeTruthy();
});
it('should apply correct state when mode is "create" and locationData is present',
fakeAsync(() => {
// Arrange
component.mode = 'create';
component['locationData'] = [{ id: '1', name: 'Node 1' }] as any;
// Act
component.ngOnInit();
tick(100);
// Assert
expect(clearInterval).toHaveBeenCalled();
expect(instrcutionServiceSpyApplyInstruction ).toHaveBeenCalled();
}));
})
instructionService.ts
public instruction: BehaviorSubject<Instructions>;
set instructions(){
let state
//setting some values for state
this.instruction.next({
...state
});
}
instruction-context.component.ts
ngOninit(){
this.instructionsService.instruction.subscribe((instruction: IInstruction) => {
this.instruction = instruction;
this.instructionLevel = this.instruction && this.instruction['level'];
this.instructionContext = this.instruction && this.instruction['context'];
if (this.instructionContext) {
this.locationData = this.instructionContext['locationData'];
if (this.instructionContext['types'] && this.instructionContext['types'][this.mode]) {
this.filterNodes = this.instructionContext['types'][this.mode][
'filterNodes'
];
this.tree = this.instructionContext['types'][this.mode]['treeData'];
this.selectedDevicesCount = Array.isArray(
this.instructionContext['types'][this.mode]['selectedNodes']
)
? this.instructionContext['types'][this.mode]['selectedNodes'].length
: 0;
}
}
this.validity.emit(this.checkFormValidity());
});
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!
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.
beforeEach(() => {
instrcutionServiceSpyApplyInstruction = spyOn(instructionService, 'applyInstruction');
// !! Get rid of this line
spyOn(instructionService , 'instruction' as any).and.returnValue(of(expectedInstructions));
});