I'm having such a hard time to test a method with jest. Still learning it I'm trying to mock the result so, but I get undefined.
TS:
getEntity() {
this.referentialService?.getBusinessList(localStorage.getItem('entity')).subscribe(response => {
this.listOperationalUnit = response.filter((item:any) => item.entityType === 1 || item.entityType === 3);
this.form.controls['entityCode'].setValue(`${response[0].id} - ${response[0].label}`);
});
}
SPEC:
describe('ModalCreateUserComponent', () => {
let component: ModalCreateUserComponent;
let fixture: ComponentFixture<ModalCreateUserComponent>;
let referentialService: ReferentialService
class ReferentialServiceStub {
public getBusinessList(): any {
return of(
[
{ id: 123, label: 'Teste', entityType: 1 },
{ id: 456, label: 'Teste456', entityType: 2 },
{ id: 789, label: 'Teste789', entityType: 3 },
]
);
}
}
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ModalCreateUserComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
{ provide: ReferentialService, useClass: ReferentialServiceStub }
],
imports: [
BrowserAnimationsModule,
ReactiveFormsModule,
RouterTestingModule,
HttpClientTestingModule,
]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ModalCreateUserComponent);
component = fixture.componentInstance;
referentialService = TestBed.inject(ReferentialService);
});
it('should test', () => {
const expectResponse = [
{ id: 123, label: 'Teste', entityType: 1 },
{ id: 789, label: 'Teste789', entityType: 3 },
]
component.getEntity();
expect(component.listOperationalUnit).toBe(expectResponse)
expect(component.form.get('entityCode')?.value).toBe('123 - teste');
});
}
Expected: [{"entityType": 1, "id": 123, "label": "Teste"}, {"entityType": 3, "id": 789, "label": "Teste789"}]
Received: undefined
I also tried using Spy On
it('should test', () => {
const expectResponse = [
{ id: 123, label: 'Teste', entityType: 1 },
{ id: 789, label: 'Teste789', entityType: 3 },
]
const spy = jest.spyOn(translateService, 'getBusinessList').mockReturnValue(expectResponse);
expect(component.listOperationalUnit).toBe(expectResponse)
expect(component.newUserForm.get('entityCode')?.value).toBe('123 - teste');
});
but got the error :
No overload matches this call ´
I also tried:
it('should test', () => {
const spy = jest.spyOn(referentialService, 'getBusinessList');
component.getEntity();
expect(spy).toHaveBeenCalledWith();
});
but got the error :
Expected: called with 0 arguments Received: null
I will be very glad if someone send me some documentation to read about test subscribe with Jest and Angular, because it's been hard. =)
CodePudding user response:
I think you are really close to a solution. I would try to test the function like this:
it('should test', () => {
const expectResponse = [
{ id: 123, label: 'Teste', entityType: 1 },
{ id: 789, label: 'Teste789', entityType: 3 },
]
const spy = jest.spyOn(referentialService, 'getBusinessList').mockReturnValue(expectResponse);
component.getEntity();
fixture.detectChanges();
expect(spy).toHaveBeenCalled();
});
if your getBusinessList function returns an observable you need to mockReturn an observable containing your expectResponse with the rxjs of() function like this:
const spy = jest.spyOn(referentialService, 'getBusinessList').mockReturnValue(of(expectResponse));
Also because i noted your comment on one of the other solutions. you can easily set the values for your localStorage from inside your tests like this:
localStorage.setItem('entity', 'entity');
so for reference your test with returnType Observable would look like this:
it('should test', () => {
localStorage.setItem('entity', 'entity');
const expectResponse = [
{ id: 123, label: 'Teste', entityType: 1 },
{ id: 789, label: 'Teste789', entityType: 3 },
]
const spy = jest.spyOn(referentialService, 'getBusinessList').mockReturnValue(of(expectResponse));
component.getEntity();
fixture.detectChanges();
expect(spy).toHaveBeenCalled();
});
CodePudding user response:
What you have in your first example without the spyOn
is correct, I think you just mispelled useClass
. You have it as useclass
but it should be useClass
.
Also, you may need to use fakeAsync
and tick
.
// add fakeAsync wrapper here
it('should test', fakeAsync(() => {
const expectResponse = [
{ id: 123, label: 'Teste', entityType: 1 },
{ id: 789, label: 'Teste789', entityType: 3 },
]
component.getEntity();
// add tick to ensure the `subscribe` in the component happens
// before these assertions
tick();
expect(component.listOperationalUnit).toBe(expectResponse)
expect(component.form.get('entityCode')?.value).toBe('123 - teste');
}));
The test most likely pass without fakeAsync
and tick
but it could be good to get in the habit of using it.