[英]jasmine login test using ngrx effect Angular5
I'm testing a login effects service using jasmine with marbles 我正在使用茉莉花和大理石测试登录效果服务
It's fairly, straightforward; 这是相当直接的。 the user sends login info (email and password) via the store payload to the effect
用户通过商店有效负载发送登录信息(电子邮件和密码)到效果
the api endpoint which check credentials, responds with a token that is decoded to be used as a constructor parameter for the LoginSuccess class, within the effects service. api端点,用于检查凭据,并使用一个令牌进行响应,该令牌经过解码以用作effects服务中LoginSuccess类的构造函数参数。
I've gotten it working, however, I'm finding that the test reaches out to the "real" effects service and returns an object "userState". 我已经开始使用它了,但是,我发现测试到达了“真实”效果服务并返回了一个对象“ userState”。
This object I am mocking in the test also (along with using createSpyObj
for the authService, which works) 这个对象,我在测试中还嘲讽(连同使用
createSpyObj
的authService,它的工作原理)
If the objects don't match (including having matching tokens, which I had to copy from a real login) the test fails, I'm a little lost on this one if someone could give some pointers 如果对象不匹配(包括具有匹配的令牌,我必须从真实登录名中复制这些对象),则测试失败,如果有人可以提供一些指针,我对此会有些迷失
The effects file: 效果文件:
export class LoginEffects {
constructor(private actions$: Actions,
private authService: AuthService,
private router: Router) {}
@Effect() login$: Observable<any> = this.actions$
.pipe(
ofType<LogIn>(LOGIN),
mergeMap(action => {
return this.authService.login(action.payload.email, action.payload.password)
.pipe(
map((data)=> {
//Decode the returned jwt
let decodedData = jwt_decode(data.token);
//userState is being mocked in test as well
let userState:loginReducer.State = {
isAuthenticated: true,
token:data.token,
name:decodedData.name
}
console.log(userState)
return new LoginSuccess(userState)
}),
catchError((error) => {
return Observable.of(new LogInFailure({ error: error }));
})
)
}),
)
}
test file: 测试文件:
import { LoginEffects } from "./login.effects";
import { TestBed, fakeAsync } from "@angular/core/testing";
import { provideMockActions } from '@ngrx/effects/testing';
import {of} from 'rxjs/observable/of';
import { cold } from 'jasmine-marbles';
import { AuthService } from "../../../services/auth.service";
import {RouterTestingModule} from "@angular/router/testing";
import { Observable } from "rxjs";
import * as EffectsAction from '../actions/login.actions';
import { StoreModule} from "@ngrx/store";
import { reducers } from "../../../reducers";
describe('LoginEffects', () => {
let effects, authService;
let actions$: Observable<any>;
beforeEach(() => TestBed.configureTestingModule({
imports: [
RouterTestingModule,
StoreModule.forRoot(reducers, {})
],
providers: [
LoginEffects,
{
provide: AuthService,
useValue: jasmine.createSpyObj('authService', ['login'])
},
provideMockActions(() => actions$)
]
}));
beforeEach(() => {
effects = TestBed.get(LoginEffects);
authService = TestBed.get(AuthService);
});
describe('Effects', () => {
it('should return response from server', () => {
// service = TestBed.get(AuthService);
const payloadInfo = {email: 'test@reflections.co.uk', password:'password'}
const userState = {
isAuthenticated: true,
//copied token token:'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiTHVrZSIsImlhdCI6MTUzMTQwMTgyOSwiZXhwIjoxNTMxNDAzMDI5LCJzdWIiOiI1OWM3ODA4YzE3Y2UzZTc1ODU4M2RjOWEifQ.Kr6NfLc9mgz8_O6wlnAo1E4jTSE0Q3tB4vqwIQOVWcasSm8MlPPmvx1WqLkRkKx1r_Rba0bjGIQ7iypZNW-XJEqr25GCnL3gparJap5CWqd_4dea48cNbcM_Km5cCkQ746IBVt2uarrqxBMvp4HAp2mP6E-A1XuV04p6VcnincGxwCW5lTQNFySKSVZ-cOOLOdlyhYhsvvPvu-f7J3W0poqniEJICkFaVnweBWogDUonqe_48z_eRauLkIdeLBPj3PO67XVgIGe423P15ZXXmmrXNFT4iGsCSfG_MJdljgTaZl65UcD_bu8wRkYTd4Vh0qBIuULyem4YDolaFMhcKg',
name:'Luke'
}
const action = new EffectsAction.LogIn({type:'LOGIN', payload:payloadInfo});
const result = new EffectsAction.LoginSuccess(userState)
actions$ = of(action);
const response = cold( 'a', {a : userState})
const expected = cold( 'b', {b : result})
authService.login.and.returnValue(response);
console.log(expected)
expect(effects.login$).toBeObservable(expected);
});
});
});
Basically, it was to do with decoding the response sent from the authService And assigning the data to properties of the userState: 基本上,这与解码从authService发送的响应并将数据分配给userState的属性有关:
//Decode the returned jwt
console.log(data)//This would be my mockdetails
let decodedData = jwt_decode(data.token);
console.log(decodedData)//This would have the details from logged in user
let userState:loginReducer.State = {
isAuthenticated: true,
token:data.token,
name:decodedData.name//this is from logged in user throws error
}
console.log(userState)//This would have the details from logged in user
What this seemed to be doing was; 这似乎是在做; extracting the real logged in user info into memory when decoding and applying to the userState object
解码并应用于userState对象时,将实际登录的用户信息提取到内存中
I saw that I didn't need to decode to get the username I could just grab it from the returned object: 我看到我不需要解码就可以从返回的对象中获取用户名:
map((data)=> {
let userState:loginReducer.State = {
isAuthenticated: true,
token:data.token,
name:data.name
}
})
So it works but I couldn't work out what to do if I had to decode? 这样就可以了,但是如果我必须解码,我就无法解决该怎么办?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.