在为我们在angular应用程序中编写的auth guard实现Spec文件时,给了我一个错误,我无法思考发生了什么。
Auth Guard -------------> should return FALSE if the user state is not logged in FAILED
TypeError: actual.subscribe is not a function
at VirtualAction.<anonymous> (node_modules/jasmine-marbles/es6/index.js:55:1)
at VirtualAction._execute (node_modules/rxjs/_esm2015/internal/scheduler/AsyncAction.js:51:1)
at VirtualAction._execute (node_modules/rxjs/_esm2015/internal/scheduler/VirtualTimeScheduler.js:59:1)
at VirtualAction.execute (node_modules/rxjs/_esm2015/internal/scheduler/AsyncAction.js:39:1)
at TestScheduler.flush (node_modules/rxjs/_esm2015/internal/scheduler/VirtualTimeScheduler.js:16:1)
at TestScheduler.flush (node_modules/rxjs/_esm2015/internal/testing/TestScheduler.js:107:1)
at toBeObservableComparer (node_modules/jasmine-marbles/es6/index.js:77:1)
at <Jasmine>
at UserContext.<anonymous> (src/app/core/guards/auth.guard.spec.ts:55:37)
以上是我在为auth.guard.spec.ts和auth.guard.ts粘贴以下代码时所面临的问题
import { TestBed } from '@angular/core/testing';
import { combineReducers, Store, StoreModule } from '@ngrx/store';
import { cold } from 'jasmine-marbles';
import { addMatchers, initTestScheduler } from 'jasmine-marbles';
import { RouterTestingModule } from '@angular/router/testing';
import { provideMockStore } from '@ngrx/store/testing';
import { AuthGuard } from './auth.guard';
import * as fromRoot from '../../app-state';
import * as fromAuth from '../../modules/auth/store/auth.reducer';
import * as fromAuthActions from '../../modules/auth/store/auth.actions';
import { User } from '../../modules/auth/login/login.model';
import { LogInComponent } from '../../modules/auth/login/login.component';
describe('Auth Guard', () => {
let guard: AuthGuard;
let store: Store<any>;
const initialState = { loggedIn: false };
beforeEach(() => {
initTestScheduler();
addMatchers();
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([
{ path: 'auth', component: LogInComponent }
]),
StoreModule.forRoot({
...fromRoot.reducers,
auth: combineReducers(fromAuth.reducer)
})
],
providers: [
AuthGuard,
provideMockStore({ initialState })
]
});
store = TestBed.inject(Store);
spyOn(store, 'dispatch').and.callThrough();
guard = TestBed.inject(AuthGuard);
});
it('-------------> should return FALSE if the user state is not logged in', () => {
const expected = cold('(a|)', { a: false });
expect(guard.canActivate()).toBeObservable(expected);
});
});
guard.ts
import { Injectable } from '@angular/core';
import { Router, CanActivate } from '@angular/router';
import { Observable } from 'rxjs';
import { Store } from '@ngrx/store';
import { AppState } from 'src/app/app-state';
import * as fromAuth from '../../modules/auth/store/auth.reducer';
@Injectable()
export class AuthGuard implements CanActivate {
authState: Observable<fromAuth.AuthState>;
constructor(private store: Store<AppState>, private router: Router) { }
canActivate(): boolean {
// Check if user is authenticated or not i.e. only logged in users havce access to todos page
const authState = this.store.select(fromAuth.selectAuthState);
authState.subscribe(state => {
if (!state.isAuthenticated) {
this.router.navigate(['auth']);
return false;
}
});
return true;
}
}
发布于 2021-10-04 15:23:54
我认为由于您的canActivate
返回的是boolean
而不是Observable<boolean>
,这可能是问题所在。
尝试这样更改您的canActivate
:
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
....
canActivate(): Observable<boolean> {
// Check if user is authenticated or not i.e. only logged in users have access to todos page
return this.store.select(fromAuth.selectAuthState).pipe(
map(state => {
if (!state.isAuthenticated) {
this.router.navigate(['auth']);
return false;
}
return true;
}),
);
}
现在,我们将返回一个可观察对象,然后在您的测试中,expect(guard.canActivate()).toBeObservable(...)
应该可以工作。在此之前,guard.canActivate()
是boolean
而不是Observable
。
https://stackoverflow.com/questions/69397918
复制相似问题