Estou com dificuldade em entender o Jasmine Spies para serviços com dependências injetadas no construtor
Tenho um serviço de conta com o Constructor
constructor(private readonly api: ApiService,private readonly authorityService: AuthorityService) {}
No serviço Conta, tenho um método que usa o authorityService (definido no construtor) para verificar uma permissão antes de retornar um valor
public async getAccount(): Promise<Account | null> {
if (this.authorityService.hasAuthority(Authority.PERM_ACCOUNT_READ)) {
this.account = await this.api.get<Account>('/admin/rest/account');
return this.account;
}
return null;
}
O que estou tentando fazer é fornecer testes unitários para o método getAccount. O que eu quero é garantir que quando authorityService.hasAuthority(Authority.PERM_ACCOUNT_READ) retorne true ou false
No meu teste, configurei o seguinte no meu arquivo .spec.ts
stub do authService
class authorityServiceStub{
hasAuthority(str: string): boolean {
return false;
}
}
então no meu bloco describe eu tenho o seguinte
fdescribe('AccountService', () => {
let service: AccountService;
let httpTestingController:HttpTestingController
let authorityServiceDependency:AuthorityService;
/**
* Sets up the testing module before each test case.
*/
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [],
providers: [provideHttpClient(),
provideHttpClientTesting(),
AccountService,{
provide: AuthorityService,
useClass: authorityServiceStub
}
],
})
service = TestBed.inject(AccountService);
authorityServiceDependency = TestBed.inject(AuthorityService);
httpTestingController = TestBed.inject(HttpTestingController);
}));
no meu primeiro teste onde quero garantir se a permissão é falsa, meu objeto Account de getAccount() em nulo
it('should return null if not permissions and not forced', async() => {
spyOn(authorityServiceDependency, 'hasAuthority').withArgs(Authority.PERM_ACCOUNT_READ).and.returnValue(false);
const account = await service.getAccount();
expect(account).toBeNull();
expect(authorityServiceDependency.hasAuthority).toHaveBeenCalledWith(Authority.PERM_ACCOUNT_READ);
const req = httpTestingController.match((request) =>
request.url.includes("/admin/rest/account")
);
});
Este teste passa
mas no outro caso onde eu quero testar quando a permissão está definida e validar se a conta não é nula eu tenho o seguinte
it('should return the account if the permissions are set', async() => {
const accountData = {firstName: 'Test',lastName:"tester"} as Account;
spyOn(authorityServiceDependency, 'hasAuthority').withArgs(Authority.PERM_ACCOUNT_READ).and.returnValue(true);
spyOn(service, 'getAccount').and.returnValue(Promise.resolve(accountData));
service.getAccount().then((account) => {
expect(account).not.toBeNull();
expect(account?.firstName).toEqual("Test");
expect(account?.lastName).toEqual("tester");
expect(service.getAccount).toHaveBeenCalled();
});
expect(authorityServiceDependency.hasAuthority).toHaveBeenCalledWith(Authority.PERM_ACCOUNT_READ);
const req = httpTestingController.match((request) =>
request.url.includes("/admin/rest/account")
);
});
a expectativaexpect(authorityServiceDependency.hasAuthority).toHaveBeenCalledWith(Authority.PERM_ACCOUNT_READ);
está falhando com a mensagem
Esperava-se que o spy hasAuthority tivesse sido chamado com: [ 'PERM_ACCOUNT_READ' ], mas ele nunca foi chamado. em UserContext. (src/app/core/services/account/account.service.spec.ts:86:53) em Generator.next () em asyncGeneratorStep (node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:3:1) em _next (node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js:17:1)
Eu sei que é algo que estou fazendo incorretamente, mas pela minha vida eu não consigo fazer isso funcionar como eu quero. Não está claro se configurar a classe simulada no meu teste é a abordagem correta... parece desajeitado, mas eu li essa abordagem em algum lugar na internet e parece fazer sentido, mas estou meio fora do meu elemento aqui e apreciaria qualquer insight/orientação