问题
Running command:
ng test --codeCoverage=true --progress=false --watch=false
Error message:
TypeError: Cannot read property 'substring' of undefined
NgOnInit of the component
private serv: ExtratosMensaisService,
ngOnInit(): void {
const serventia: Serventia = this.serv.getServentiaSelecionada();
const competencia: Competencia = this.serv.getCompetenciaSelecionada();
const titularidade = serventia.titularidade.substring(0, 1).toUpperCase();
}
The service file method:
getServentiaSelecionada(): Serventia {
return JSON.parse(sessionStorage.getItem('serventia'));
}
I understand that the attribute is undefined, but I can't make it 'defined'. I already tried to use the third array from the jasmine.createSpyObj() to spy on properties but the error continues. And tried to pass an JSON object on the mockExtratosMensaisService returnValue(of({ object })), and tried this:
mockExtratosMensaisService.getServentiaSelecionada.and.returnValue(of({ titularidade: 123 }));
Am I using the wrong approach? I need this test to pass.
spec.component file:
describe('PrestacaoContasTitularComponent', () => {
let component: PrestacaoContasTitularComponent;
let fixture: ComponentFixture<PrestacaoContasTitularComponent>;
const mockExtratosMensaisService = jasmine.createSpyObj('Obj',
['getServentiaSelecionada', 'getCompetenciaSelecionada'],
['titularidade']);
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ RouterTestingModule, HttpClientTestingModule ],
declarations: [ PrestacaoContasTitularComponent ],
providers: [ MatDialog, Overlay, MatSnackBar,
{ provide: ActivatedRoute, useValue: {} },
{ provide: InjectionToken, useValue: {} },
{ provide: MAT_DIALOG_SCROLL_STRATEGY, useValue: {} },
{ provide: ExtratosMensaisService, useValue: mockExtratosMensaisService }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PrestacaoContasTitularComponent);
component = fixture.componentInstance;
mockExtratosMensaisService.getServentiaSelecionada.and.returnValue(of({ titularidade: 123 }));
mockExtratosMensaisService.getCompetenciaSelecionada.and.returnValue(of({ data: 'competencia' }));
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
回答1:
Try changing the mock to:
const mockExtratosMensaisService = jasmine.createSpyObj('Obj', ['getServentiaSelecionada', 'getCompetenciaSelecionada']);
And then doing
mockExtratosMensaisService.getServentiaSelecionada.and.returnValue({ titularidade: 'abc' });.
I changed 123 to 'abc' because I am not sure if substring would work on a number. Before, you were still returning of and this is not correct because it is not an observable, it is a regular JavaScript object.
回答2:
Your approach with: mockExtratosMensaisService.getServentiaSelecionada.and.returnValue(of({ titularidade: 123 }));
is quite good.
But you need a spy object that you can call .and.returnValue()
To get this you can do like: spyOn(mockExtratosMensaisService, 'getServentiaSelectionada').and.returnvalue(of({titularidade: 123}))
This should be a way to go.
来源:https://stackoverflow.com/questions/62876364/jasmine-angular-mock-component-attribute