因模拟模拟错误而未对茉莉花期望进行测试/评估的问题 [英] Issue with jasmine expectations not being tested/evaluated because of simulated mock error

查看:179
本文介绍了因模拟模拟错误而未对茉莉花期望进行测试/评估的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图对一个角度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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆