#angular #typescript #mocking #jasmine #spy
Вопрос:
Я пытаюсь создать маршрут API в шпионской службе, используя Jasmine.
Я очень новичок в Angular, Typescript и Jasmine, поэтому я не могу сказать, чего мне не хватает в моем коде, должен ли я вставлять код в beforeEach
или в свой собственный it('should do xyz...')
и т. Д.
Я считаю , что должен запускать макет внутри beforeEach
, но я сталкиваюсь с ошибкой с полезной нагрузкой (см. Примечания ниже).
технические характеристики:
providers: [
{ provide: MyService, useValue: CommonServiceSpies.createHttpClientSpy()},
]
beforeEach(() => {
fixture = TestBed.createComponent(ManagerComponent);
const myVar = TestBed.inject(MyService) as jasmine.SpyObj<MyService>;
const payload = 123 // I'd had an object that resembled the payload from the component.ts file, but it's not working with how the service was set up // Error received was: "Account of type Observable<{}> is not assignable to param of type 'Observable<number>'"
myVar.GetRemainingAmount.and.returnValue(of(payload)); // Testing window err: "cannot read property 'and' of undefined"
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
сервис.ts:
export class MyService {
constructor(
private http: HttpClient
) { }
GetRemainingAmount(request: RemainingAmountRequest): Observable<number> {
return this.http.post<number>('/some-route', request);
}
менеджер-компонент.ts:
constructor(
public myService: MyService
) { }
hasRemainingSpend() : void {
const payload: RemainingAmountRequest = {
accountId: this.account.id,
otherId: this.xyz?.id
}
this.myService.GetRemainingAmount(payload).subscribe((response: number) => {
this.warningSpend = response;
if (this.warningSpend < this.rate.value || this.warningSpend == null) {
// call another func
// this is working as expected
}
})
}
Ответ №1:
Я не уверен, что CommonServiceSpies.createHttpClientSpy()
это делает, но я могу предположить, что это создает HTTP-шпиона.
Это хороший ресурс для тестирования угловых блоков, но он также показывает, как имитировать внешние зависимости.
Я бы сделал:
// before the first beforeEach, create a variable that will be a Spy Object
let mockMyService: jasmine.SpyObj<MyService>;
// Inside of the first beforeEach (TestBed.configureTestingModule),
// assign a value to the variable
// The first argument is a string for debugging purposes and the
// the second array of strings are public methods you would like to mock
mockMyService = jasmine.createSpyObj<MyService>('MyService', ['GetRemainingAmount']);
providers: [
// provide the mock we just created
{ provide: MyService, useValue: mockMyService},
]
beforeEach(() => {
fixture = TestBed.createComponent(ManagerComponent);
// return an empty object for this method
myService.GetRemainingAmount.and.returnValue(of({}));
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
Если вы не хотите этого делать, вы можете исправить то, что у вас есть, выполнив следующие действия:
Измените эту строку:
myVar.GetRemainingAmount.and.returnValue(of(payload));
Для:
spyOn(myVar, 'GetRemainingAmount').and.returnValue(of({}));