我正在为我的effect.ts文件编写单元测试。但是由于某种原因,即使我更改了Expect语句以调度ContactInfoFailed操作,它也会通过。我的测试文件中的订阅有问题吗?我无法弄清楚这是什么根本原因!还是有更好的方法编写此测试? 请在下面查看我的效果及其测试用例。
// effects.ts
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
) { }
}
// effects.spec.ts
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));
});
});
});
答案 0 :(得分:0)
delay()运算符是可能导致测试无法按预期进行的一个原因。 delay()运算符使您的流/效果完全异步。
为了正确地测试异步流,您应该使您的测试断言异步,或者更推荐使用,您可以通过模拟调度程序来同步调度流。这里是一些有用的链接,在其中进行讨论和解释:
Testing and mocking lettable operators in RxJS 5.5
https://github.com/redux-observable/redux-observable/issues/180
https://github.com/angular/angular/issues/25457
如您所见,这是一个常见问题,无论如何该解决方案都不是完美的。
提示:您可以尝试暂时删除delay()运算符,并查看其是否有效。
希望这会有所帮助!