因模拟模拟错误而未对茉莉花期望进行测试/评估的问题 [英] Issue with jasmine expectations not being tested/evaluated because of simulated mock error
问题描述
我试图对一个角度2组件进行单元测试并模拟来自http后端的错误(400 /错误请求)。
I am trying to unit test a angular 2 component and simulate an error (400/bad request) from the http backend.
这是我的代码:
describe('Component: UserAccountActivationComponent', () => {
let fixture: ComponentFixture<UserAccountActivationComponent>;
let userAccountActivationComponent: UserAccountActivationComponent;
const observableMock = Observable.of('Some Observable');
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [
MockBackend,
BaseRequestOptions,
{
provide: Http,
useFactory: (backend, options) => new Http(backend, options),
deps: [MockBackend, BaseRequestOptions]
},
{
provide: ActivatedRoute, useClass: RouteMock
},
],
imports: [AppModule, HttpModule]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(UserAccountActivationComponent);
userAccountActivationComponent = fixture.componentInstance;
});
it('should not signin user nor navigate to dashboard if account is not activated', fakeAsync(inject(
[UserAccountService, SessionSigninService, Router, MockBackend],
(userAccountService: UserAccountService, signinService: SessionSigninService, router: Router, mockBackend: MockBackend) => {
const opts = {
type: ResponseType.Error,
status: 400
};
const responseOpts = new ResponseOptions(opts);
mockBackend.connections.subscribe(
(connection: MockConnection) => {
connection.mockError(new MockError(responseOpts));
});
const activateSpy = spyOn(userAccountService, 'activateAccount').and.callThrough();
const signinSpy = spyOn(signinService, 'signinByUserAccountToken').and.returnValue(observableMock);
const navigateSpy = spyOn(router, 'navigate').and.returnValue(observableMock);
fixture.detectChanges();
tick();
expect(activateSpy).toHaveBeenCalled();
expect(signinSpy).not.toHaveBeenCalled();
expect(navigateSpy).not.toHaveBeenCalled();
})));
});
class MockError extends Response implements Error {
name: any;
message: any;
}
class RouteMock {
readonly params = Observable.of({userAccountToken: 'a-token'});
}
我正在模拟 userAccountService中发生的错误。 activateAccount
方法。我只想检查是否既没有 signinService.signinByUserAccountToken
也没有调用 router.navigate
。这就是我想要的茉莉花期望:
I am simulating an error occurring in the userAccountService.activateAccount
method. I just want to check that neither signinService.signinByUserAccountToken
nor the router.navigate
are called. This is what I am trying to do with the jasmine expectations:
expect(activateSpy).toHaveBeenCalled();
expect(signinSpy).not.toHaveBeenCalled();
expect(navigateSpy).not.toHaveBeenCalled();
但是,模拟错误导致测试停止:
However, I the test is stopped by the simulated error:
Chrome 56.0.2924 (Mac OS X 10.12.3) Component: UserAccountActivationComponent should not signin user nor navigate to dashboard if account is not activated FAILED
Error: Error in :0:0 caused by: Response with status: 400 null for URL: null
at ViewWrappedError.ZoneAwareError (webpack:///~/zone.js/dist/zone.js:811:0 <- src/test.ts:142448:33)
at ViewWrappedError.BaseError [as constructor] (webpack:///~/@angular/core/src/facade/errors.js:22:0 <- src/test.ts:36304:16)
at ViewWrappedError.WrappedError [as constructor] (webpack:///~/@angular/core/src/facade/errors.js:87:0 <- src/test.ts:36369:16)
at new ViewWrappedError (webpack:///~/@angular/core/src/linker/errors.js:77:0 <- src/test.ts:70405:16)
at proxyClass.DebugAppView._rethrowWithContext (webpack:///~/@angular/core/src/linker/view.js:653:0 <- src/test.ts:111685:23)
at proxyClass.DebugAppView.detectChanges (webpack:///~/@angular/core/src/linker/view.js:626:0 <- src/test.ts:111658:18)
at ViewRef_.detectChanges (webpack:///~/@angular/core/src/linker/view_ref.js:170:0 <- src/test.ts:71336:20)
at ComponentFixture._tick (webpack:///~/@angular/core/bundles/core-testing.umd.js:196:0 <- src/test.ts:15653:36)
at webpack:///~/@angular/core/bundles/core-testing.umd.js:210:45 <- src/test.ts:15667:53
at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:242:0 <- src/test.ts:141879:26)
at ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:79:0 <- src/test.ts:98996:39)
at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:241:0 <- src/test.ts:141878:32)
at Object.onInvoke (webpack:///~/@angular/core/src/zone/ng_zone.js:271:0 <- src/test.ts:38049:37)
at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:241:0 <- src/test.ts:141878:32)
at Zone.run (webpack:///~/zone.js/dist/zone.js:113:0 <- src/test.ts:141750:43)
仅供参考,这是待测组件:
FYI, here is the component under test:
@Component({
templateUrl: './useraccount-activation.component.html'
})
export class UserAccountActivationComponent implements OnInit {
constructor(private userAccountService: UserAccountService,
private signinService: SessionSigninService,
private router: Router,
private route: ActivatedRoute) {
}
ngOnInit() {
this.route.params
.take(1)
.pluck('userAccountToken')
.switchMap((userAccountToken: string) =>
this.userAccountService.activateAccount(userAccountToken)
.switchMapTo(this.signinService.signinByUserAccountToken(userAccountToken))
)
.subscribe(() => this.router.navigate(['/dashboard']));
}
}
编辑1 :很遗憾,更改为:
mockBackend.connections.subscribe(
(connection: MockConnection) => {
responseOpts.url = connection.request.url;
connection.mockError(new MockError(responseOpts));
});
仍然会导致以下错误:
'HttpClient error: ', MockError{_body: null, status: 400, ok: false, statusText: null, headers: null, type: 3, url: '/api/useraccount/activate/a-valid-token'}
Error: Error in :0:0 caused by: Response with status: 400 null for URL: /api/useraccount/activate/a-valid-token
at Error.ZoneAwareError (webpack:///~/zone.js/dist/zone.js:958:0 <- src/test.ts:143513:33)
at ZoneAwareError (webpack:///~/zone.js/dist/zone.js:955:0 <- src/test.ts:143510:35)
at wrappedError (webpack:///~/@angular/core/src/error_handler.js:144:21 <- src/test.ts:36697:34)
at viewWrappedError (webpack:///~/@angular/core/src/linker/errors.js:65:21 <- src/test.ts:70785:125)
at proxyClass.DebugAppView._rethrowWithContext (webpack:///~/@angular/core/src/linker/view.js:656:0 <- src/test.ts:112336:111)
at proxyClass.DebugAppView.detectChanges (webpack:///~/@angular/core/src/linker/view.js:629:0 <- src/test.ts:112309:18)
at ViewRef_.detectChanges (webpack:///~/@angular/core/src/linker/view_ref.js:172:0 <- src/test.ts:71715:20)
at ComponentFixture._tick (webpack:///~/@angular/core/bundles/core-testing.umd.js:196:0 <- src/test.ts:15805:36)
at webpack:///~/@angular/core/bundles/core-testing.umd.js:210:45 <- src/test.ts:15819:53
at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:330:0 <- src/test.ts:142885:26)
at ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:79:0 <- src/test.ts:99788:39)
at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:329:0 <- src/test.ts:142884:32)
at Object.onInvoke (webpack:///~/@angular/core/src/zone/ng_zone.js:273:0 <- src/test.ts:38516:37)
at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:329:0 <- src/test.ts:142884:32)
at Zone.run (webpack:///~/zone.js/dist/zone.js:126:0 <- src/test.ts:142681:43)
推荐答案
我认为你得到了例外,因为没有指定 Url
。尝试在以下选项上设置网址:
It looks to me like you are getting the exception because the Url
is not specified. Try setting the url on the options like so:
let responseOpts = new ResponseOptions(opts);
mockBackend.connections.subscribe(
(connection: MockConnection) => {
responseOpts.url = connection.request.url;
connection.mockError(new MockError(responseOpts));
});
编辑1
您的问题是看到可能是因为错误没有被捕获到任何地方,所以它正在冒泡到区域。尝试向您的订阅添加错误捕获以处理异常或压制错误,(错误)=> {}
。
this.route.params
.take(1)
.pluck('userAccountToken')
.switchMap((userAccountToken: string) =>
this.userAccountService.activateAccount(userAccountToken)
.switchMapTo(this.signinService.signinByUserAccountToken(userAccountToken))
)
.subscribe(() => this.router.navigate(['/dashboard']), (error) => {});
这篇关于因模拟模拟错误而未对茉莉花期望进行测试/评估的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!