我正在测试一项简单的服务.该服务使用来自其他服务的2个值.
基本上,我想测试这两个值:isLogged = false和isLogged = true.
是否可以仅更改注入服务的值,还是需要执行其他操作? (我不知道,所以如果你能带路我,我会很感激).
这是我的测试代码:
编辑我找到了解决问题的方法.您需要将提供程序注入到inject参数中,然后您可以根据需要更改其属性.
import { TestBed,async,inject } from '@angular/core/testing'; import { AuthGuardService } from './authguard.service'; import { Router } from '@angular/router'; import { AuthService } from './auth.service'; describe('AuthguardService',() => { let calledUrl = '/logged/main/last'; let authServiceStub = { isLogged: false,redirectUrl: calledUrl }; class RouterStub { navigate(url: string) { return url; } }; beforeEach(() => { TestBed.configureTestingModule({ providers: [ AuthGuardService,{ provide: AuthService,useValue: authServiceStub },{ provide: Router,useClass: RouterStub },] }); }); it('should ...',inject([AuthGuardService,Router],(service: AuthGuardService,router: Router) => { let spy = spyOn(router,'navigate'); service.checkLoginState(calledUrl); expect(spy).toHaveBeenCalledWith(['/login']); })); });
解决方法
您声明的解决方案是单向的.如果要完成的只是更改测试中的值,更简洁的方法就是直接更改authServiceStub中的值:
// inside tests: authServiceStub.isLogged = false; ... authServiceStub.isLogged = true;
^简单但不是非常封装.
或参数化它:
let isLogged: false; let authServiceStub = { isLogged: isLogged,redirectUrl: calledUrl }; ... // inside tests: isLogged = false; ... isLogged = true;
^简洁但仍未封装.
或者添加一个setter:
let authServiceStub = { isLogged: false,setLogged: function(logged) { this.isLogged = logged; },redirectUrl: calledUrl }; ... // inside tests: setLogged(false); ... setLogged(true);
^更多封装.可以与您的注射方法结合使用.
或者如果isLogged作为函数重新实现,则可以使用spyOn:
// inside tests: spyOn(authServiceStub,"isLogged").and.returnValue(false); ... spyOn(authServiceStub,"isLogged").and.returnValue(true);
^更多黑盒子,可能更灵活/面向未来,特别是如果与您的注射解决方案结合使用(因为您可以彻底改变存根或模拟并仍然获得您想要的行为).这是更多的工作,所以可能不值得.但是以这种黑盒方式考虑AuthService可能会让你有理由将isLogged重构为函数(或不).