如何对这种效果进行单元测试(使用 {dispatch: false})?
How to unit test this effect (with {dispatch: false})?
这里是 ngrx 和单元测试初学者。我的效果如下:
@Injectable()
export class NotificationEffects {
@Effect({dispatch: false})
notificationShow$ = this.actions$
.ofType(notificationAction.NOTIFICATION_SHOW)
.do((action: notificationAction.NotificationShowAction) => {
this.notificationService.info(action.payload.config);
});
constructor(private actions$: Actions, private notificationService: NotificationService) {}
}
具体来说,我想测试notificationService方法信息是否被调用。我该怎么做?
我已经按照这些示例进行操作,但没有找到解决方案:
https://netbasal.com/unit-test-your-ngrx-effects-in-angular-1bf2142dd459
https://medium.com/@adrianfaciu/testing-ngrx-effects-3682cb5d760e
https://github.com/ngrx/effects/blob/master/docs/testing.md
所以就这么简单:
describe('notificationShow$', () => {
let effects: NotificationEffects;
let service: any;
let actions$: Observable<Action>;
const payload = {test: 123};
beforeEach( () => {
TestBed.configureTestingModule( {
providers: [
NotificationEffects,
provideMockActions( () => actions$ ),
{
provide: NotificationService,
useValue: jasmine.createSpyObj('NotificationService', ['info'])
}
]
} );
effects = TestBed.get(NotificationEffects);
service = TestBed.get(NotificationService);
});
it('should call a notification service method info with a payload', () => {
actions$ = cold('a', { a: new notificationAction.NotificationShowAction(payload) });
effects.notificationShow$.subscribe(() => {
expect(service.info).toHaveBeenCalledWith(payload);
});
});
});
it('should call a notification service method info with a payload', () => {
actions$ = cold('a', { a: new notificationAction.NotificationShowAction(payload) });
effects.notificationShow$.subscribe(() => {
expect(service.info).toHaveBeenCalledWith(payload);
});
});
它运行良好,但问题是发生错误时。在这种情况下,错误不会报告给测试运行器(在我的例子中是开玩笑)。我需要添加 try catch 块来获取错误:
it('should call a notification service method info with a payload', () => {
actions$ = cold('a', { a: new notificationAction.NotificationShowAction(payload) });
effects.notificationShow$.subscribe(() => {
try {
expect(service.info).toHaveBeenCalledWith(payload);
} catch (error) {
fail('notificationShow$: ' + error);
}
});
});
最简单的(也是官方推荐的)方法是这样做:
it('should navigate to the customers detail page', () => {
actions$ = of({ type: '[Customers Page] Customer Selected', name: 'Bob' });
// create a spy to verify the navigation will be called
spyOn(router, 'navigateByUrl');
// subscribe to execute the Effect
effects.selectCustomer$.subscribe();
// verify the navigation has been called
expect(router.navigateByUrl).toHaveBeenCalledWith('customers/bob');
});
这里是the source.
If someone interested without explicit subscription of effect and using only jasmine-marbles
it('should call a notification service method info with a payload', () => {
actions$ = cold('a', { a: new notificationAction.NotificationShowAction(payload) });
// `toBeObservable` will subscribe the effect and does the trick
expect(effects.notificationShow$).toBeObservable(actions$);
expect(service.info).toHaveBeenCalledWith(payload);
});
这里是 ngrx 和单元测试初学者。我的效果如下:
@Injectable()
export class NotificationEffects {
@Effect({dispatch: false})
notificationShow$ = this.actions$
.ofType(notificationAction.NOTIFICATION_SHOW)
.do((action: notificationAction.NotificationShowAction) => {
this.notificationService.info(action.payload.config);
});
constructor(private actions$: Actions, private notificationService: NotificationService) {}
}
具体来说,我想测试notificationService方法信息是否被调用。我该怎么做?
我已经按照这些示例进行操作,但没有找到解决方案:
https://netbasal.com/unit-test-your-ngrx-effects-in-angular-1bf2142dd459 https://medium.com/@adrianfaciu/testing-ngrx-effects-3682cb5d760e https://github.com/ngrx/effects/blob/master/docs/testing.md
所以就这么简单:
describe('notificationShow$', () => {
let effects: NotificationEffects;
let service: any;
let actions$: Observable<Action>;
const payload = {test: 123};
beforeEach( () => {
TestBed.configureTestingModule( {
providers: [
NotificationEffects,
provideMockActions( () => actions$ ),
{
provide: NotificationService,
useValue: jasmine.createSpyObj('NotificationService', ['info'])
}
]
} );
effects = TestBed.get(NotificationEffects);
service = TestBed.get(NotificationService);
});
it('should call a notification service method info with a payload', () => {
actions$ = cold('a', { a: new notificationAction.NotificationShowAction(payload) });
effects.notificationShow$.subscribe(() => {
expect(service.info).toHaveBeenCalledWith(payload);
});
});
});
it('should call a notification service method info with a payload', () => {
actions$ = cold('a', { a: new notificationAction.NotificationShowAction(payload) });
effects.notificationShow$.subscribe(() => {
expect(service.info).toHaveBeenCalledWith(payload);
});
});
它运行良好,但问题是发生错误时。在这种情况下,错误不会报告给测试运行器(在我的例子中是开玩笑)。我需要添加 try catch 块来获取错误:
it('should call a notification service method info with a payload', () => {
actions$ = cold('a', { a: new notificationAction.NotificationShowAction(payload) });
effects.notificationShow$.subscribe(() => {
try {
expect(service.info).toHaveBeenCalledWith(payload);
} catch (error) {
fail('notificationShow$: ' + error);
}
});
});
最简单的(也是官方推荐的)方法是这样做:
it('should navigate to the customers detail page', () => {
actions$ = of({ type: '[Customers Page] Customer Selected', name: 'Bob' });
// create a spy to verify the navigation will be called
spyOn(router, 'navigateByUrl');
// subscribe to execute the Effect
effects.selectCustomer$.subscribe();
// verify the navigation has been called
expect(router.navigateByUrl).toHaveBeenCalledWith('customers/bob');
});
这里是the source.
If someone interested without explicit subscription of effect and using only
jasmine-marbles
it('should call a notification service method info with a payload', () => {
actions$ = cold('a', { a: new notificationAction.NotificationShowAction(payload) });
// `toBeObservable` will subscribe the effect and does the trick
expect(effects.notificationShow$).toBeObservable(actions$);
expect(service.info).toHaveBeenCalledWith(payload);
});