Angular ngrx效应的单元测试失败
我正在为effect.ts文件编写单元测试。但由于某些原因,即使我将expect语句更改为dispatch ContactInfoFailed action,它也会通过。我的测试文件中的订阅有问题吗?我不知道这到底是什么原因!或者是否有更好的方法编写此测试? 请在下面找到我的效果和它的测试用例 //特效Angular ngrx效应的单元测试失败,angular,unit-testing,jasmine,ngrx,ngrx-effects,Angular,Unit Testing,Jasmine,Ngrx,Ngrx Effects,我正在为effect.ts文件编写单元测试。但由于某些原因,即使我将expect语句更改为dispatch ContactInfoFailed action,它也会通过。我的测试文件中的订阅有问题吗?我不知道这到底是什么原因!或者是否有更好的方法编写此测试? 请在下面找到我的效果和它的测试用例 //特效 import { Actions, Effect, ofType } from '@ngrx/effects'; import { ContactTriageService } from '..
import { Actions, Effect, ofType } from '@ngrx/effects';
import { ContactTriageService } from '../views/contact-triage/contact-triage.service';
import {
CONTACT_INFO_RESPONSE_REQUESTED, ContactInfoSucceeded, ContactInfoFailed ,
CONTACT_INFO_SELECTION_RESPONSE_REQUESTED, ContactInfoSelectionSucceeded,
ContactInfoSelectionFailed,
ContactInfoServiceResponse
} from '../actions/actions';
import { mergeMap, map, catchError, delay } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { of } from 'rxjs';
@Injectable()
export class ContactInfoEffect {
@Effect()
fetchContactInfoResponse = this.actions.pipe(
ofType(CONTACT_INFO_RESPONSE_REQUESTED),
delay(250),
mergeMap((action) =>
this.contactTriageService.getContentInfo().
pipe(map((contacts) => new ContactInfoSucceeded(contacts)),
catchError(() => of(new ContactInfoFailed()))
),
)
)
constructor(
private actions: Actions,
private contactTriageService: ContactTriageService
) { }
}
//特效
import { TestBed } from '@angular/core/testing';
import { of, ReplaySubject, Subject, EMPTY } from 'rxjs';
import { StoreModule } from '@ngrx/store';
import { provideMockActions } from '@ngrx/effects/testing';
import { ContactInfoEffect } from './effects';
import { ContactTriageService } from '../views/contact-triage/contact-triage.service';
import { reducers } from '../reducers/reducers';
import { ContactInfoSucceeded } from '../actions/actions';
import { getContactInfoMock } from 'src/server/test/mocks';
import { ContactInfoResponse } from 'src/server/contact-info/interfaces/contact-info.interface';
describe('ContactInfoEffect', () => {
let effects: ContactInfoEffect;
let contactTriageService: ContactTriageService;
let actions: Subject<any>;
beforeEach(async () => {
TestBed.configureTestingModule({
imports: [StoreModule.forRoot(reducers)],
providers: [
ContactInfoEffect,
{
provide: ContactTriageService,
useValue: {
getContentInfo() {
return EMPTY;
}
}
},
provideMockActions(() => actions)
]
});
effects = TestBed.get(ContactInfoEffect);
contactTriageService = TestBed.get(ContactTriageService);
});
it('should dispatch `ContactInfoSucceeded` if the service returns successfully', () => {
const response:ContactInfoResponse = getContactInfoMock();
const contactTriageServiceSpy = spyOn(
contactTriageService,
'getContentInfo'
).and.returnValue(of( [
getContactInfoMock()
]));
actions = new ReplaySubject(1);
actions.next(new ContactInfoSucceeded(getContactInfoMock()));
effects.fetchContactInfoResponse.subscribe((result) => {
expect(result).toEqual(new ContactInfoSucceeded(response));
});
});
});
从'@angular/core/testing'导入{TestBed};
从'rxjs'导入{of,ReplaySubject,Subject,EMPTY};
从'@ngrx/store'导入{StoreModule};
从“@ngrx/effects/testing”导入{provideMockActions};
从“/effects”导入{ContactInfoEffect};
从“../views/contact-triage/contact-triage.service”导入{ContactTriageService};
从“../reducers/reducers”导入{reducers};
从“../actions/actions”导入{contactInfoSuccessed};
从'src/server/test/mocks'导入{getContactInfoMock};
从'src/server/contact-info/interfaces/contact-info.interface'导入{ContactInfoResponse};
描述('ContactInfoEffect',()=>{
let效应:接触信息效应;
让contactTriageService:contactTriageService;
让行动:主体;
beforeach(异步()=>{
TestBed.configureTestingModule({
导入:[StoreModule.forRoot(还原器)],
供应商:[
联系信息效应,
{
提供:联系咨询服务,
使用价值:{
getContentInfo(){
返回空;
}
}
},
provideMockActions(()=>操作)
]
});
effects=TestBed.get(ContactInfoEffect);
contactTriageService=TestBed.get(contactTriageService);
});
它('如果服务成功返回,()=>{
常量响应:ContactInfoResponse=getContactInfoMock();
const contactTriageService Spy=spyOn(
联系咨询服务,
“getContentInfo”
).及.返回值([
getContactInfoMock()
]));
动作=新的ReplaySubject(1);
下一步(新ContactInfoSuccessed(getContactInfoMock());
effects.fetchContactInfoResponse.subscribe((结果)=>{
期望(结果).toEqual(新联系人信息成功(响应));
});
});
});
导致测试无法按预期工作的一个原因是delay()操作符。delay()操作符使流/效果完全异步
为了正确地测试一个异步流,您应该使您的测试断言异步,或者更推荐,您可以通过模拟调度程序来同步调度您的流。以下是一些有用的链接,其中讨论和解释了:
正如您所看到的,这是一个常见的问题,解决方案在任何情况下都不是完美的
提示:您可以尝试暂时删除delay()操作符,看看它是否有效
希望这有帮助 感谢您回复Llorenc,即使我删除了延迟,它也无法正常工作。嗯,有趣的是,如果有,您可以共享“测试”输出吗?它认为问题可能在于“subscribe”上的回调从未被调用,对吗?我认为这一行可能是问题所在:actions=newreplaysubject(1);我的意思是,它似乎应该放在provideMockActions()函数之前,因为如果您在之后创建一个新主题,那么这个新主题没有任何订户。