我正在尝试测试登录组件。我可以模拟除字符串变量之外的所有内容。该怎么做?
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss'])
export class LoginComponent {
username: string;
password: string;
loginSpinner: boolean;
constructor(public authService: AuthService, public router: Router) {
}
login() {
this.loginSpinner = true;
this.authService.login(this.username, this.password).subscribe(() => {
this.loginSpinner = false;
if (this.authService.isLoggedIn) {
// Get the redirect URL from our auth service
// If no redirect has been set, use the default
const redirect = this.authService.redirectUrl ? this.authService.redirectUrl : '/';
// Redirect the user
this.router.navigate([redirect]);
}
}, () => {
// also want to hide the spinner on an error response from server when attempting login
this.loginSpinner = false;
});
}
logout() {
this.authService.logout();
}
}
登录组件具有一个名为authService的服务。我可以模拟除authService中称为重定向URL的字符串以外的所有内容。该怎么做?
import {LoginComponent} from './login.component';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA} from '@angular/core';
import {AuthService} from './auth.service';
import {HttpClient, HttpHandler} from '@angular/common/http';
import {JwtHelperService, JwtModule, JwtModuleOptions} from '@auth0/angular-jwt';
import {TokenService} from './token.service';
import {Router} from '@angular/router';
import {Observable, of} from 'rxjs';
describe('LoginComponent', () => {
let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
const JWT_Module_Options: JwtModuleOptions = {
config: {
tokenGetter: function () {
return '';
},
whitelistedDomains: []
}
};
const authServiceSpy = jasmine.createSpyObj('AuthService', ['login', 'isLoggedIn']);
authServiceSpy.login.and.callFake(function () {
return of({});
});
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
JwtModule.forRoot(JWT_Module_Options)
],
declarations: [LoginComponent],
providers: [HttpClient, HttpHandler, JwtHelperService, TokenService,
[
{
provide: AuthService,
useValue: authServiceSpy
},
{
provide: Router,
useClass: class {
navigate = jasmine.createSpy('navigate');
}
}]],
schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should log in properly without redirect URL', () => {
authServiceSpy.isLoggedIn.and.callFake(function () {
return true;
});
component.login();
expect(component.router.navigate).toHaveBeenCalledWith(['/']);
expect(component.loginSpinner).toEqual(false);
});
it('should log in properly with redirect URL', () => {
authServiceSpy.isLoggedIn.and.callFake(function () {
return true;
});
// this doesn't work
authServiceSpy.redirectUrl = '/foo';
component.login();
expect(component.router.navigate).toHaveBeenCalledWith(['/foo']);
expect(component.loginSpinner).toEqual(false);
});
}
);
答案 0 :(得分:2)
尝试一下:
const spy = spyOnProperty(authServiceSpy, 'redirectUrl').and.returnValue(
'/foo'
);
expect(authServiceSpy.redirectUrl).toBe('/foo');
expect(spy).toHaveBeenCalled();
答案 1 :(得分:2)
你可以试试吗?
创建一个模拟类:
class MockAuthService{
public redirectUrl = "/foo";
isLoggedIn(){
/*This can also be defined only for spies*/
return true;
}
}
在测试中:
describe('LoginComponent', () => {
...
let mockAuthService = new MockAuthService();
...
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [...],
declarations: [...],
providers: [...,
[
{
provide: AuthService,
useValue: mockAuthService
},
]],
schemas: [...]
}).compileComponents();
....
it('should log in properly with redirect URL', () => {
mockAuthService.redirectUrl = '/foo';
component.login();
expect(component.router.navigate).toHaveBeenCalledWith(['/foo']);
expect(component.loginSpinner).toEqual(false);
});
...
答案 2 :(得分:1)
我参加聚会有点晚,但是有一种简单的方法可以解决您已有的事情。无需开设其他课程。首先定义一个像这样的变量:
let authService: AuthService;
然后,一旦设置了测试平台,请将其设置为最后一个beforeEach()
内测试床正在使用的实际服务:
authService = TestBed.get(AuthService);
最后在测试中使用它来设置您要在.redirectUrl
上进行的操作:
// this doesn't work
authServiceSpy.redirectUrl = '/foo';
// this DOES work
authService.redirectUrl = '/foo';
工作StackBlitz。