Angular2-jwt: Cannot use AuthHttp on my tests

Created on 15 Jul 2016  路  17Comments  路  Source: auth0/angular2-jwt

Hi there,

I find out after hours of searching (and I hope I;m wrong) that I cannot use AuthHttp in my tests.

I have described a problem that I had here:
http://stackoverflow.com/questions/38397245/angular-2-rc4-unit-test-component-that-has-dependency-injection-a-service-that

But at the last update of my question you'll see the error I'm getting.

TypeError: this.authHttp.get is not a function

So I thought that I'm doing something wrong so wrote some simpler (even) components and services and always with or without dependencies I cannot access from my tests (jasmine - chromewebdriver) the function inside the AuthHttp class.

Any ideas on this? I'm still not sure if it's a bug or my bad but I can work with all the other packaes in my tests except AuthHttp and this is why i'm adding my question here also.

Thx

Most helpful comment

Hey @chenkie ,
I saw that you repopen it, is it angular2-jwt issue?
I'm still not able to test my components/services that they use it :(
Here's an other example:
http://stackoverflow.com/questions/38400655/angular-2-unit-test-error-cannot-resolve-all-parameters-for-requestoptions/

All 17 comments

Both Http and AuthHttp have providers you're not providing. AuthHttp required an AuthConfig instance to work with.

I see, shouldn't then get a message for missing provider?

you're doing this:

  let component: LogoutButtonComponent;
  let router: any = Router;
  let authHttp: any = AuthHttp;
  let http: any = Http;
  let service: any = new UserService(router, authHttp, http);

There is no injection going on there, you're passing class references (constructor functions) into your new user service.

In that case this should work?

  beforeEachProviders(() => [
    LogoutButtonComponent,
    AuthHttp,
    AuthConfig
  ]);

  beforeEach(() => {
    component = new LogoutButtonComponent(service);
  });

  it('should logout user', inject([AuthHttp], () => {
    localStorage.setItem('token', 'FOO');
    component.logout();
    expect(localStorage.getItem('token')).toBeNull();
  }));

But I'm getting:

Error: Cannot resolve all parameters for 'AuthConfig'(?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'AuthConfig' is decorated with Injectable.

PS: If this truly my bad (probably) and you wish we can move to the SO so I can close this ;)

try

{provide: AuthConfig, useValue: new AuthConfig()}

Still the same

thx @escardin I think that was it.

Thanks again.

@escardin sorry but after those two are fixed
I'm still getting for others...

Error: No provider for RequestOptions! (AuthHttp -> RequestOptions)

for example.

Is it still related?

You still have to handle your http providers. It's kind of out of scope for this lib to help you there. You probably want a mock backend though.

Ye I tried like this:

  beforeEachProviders(() => [
    LogoutButtonComponent,
    MockBackend,
    provide(Http, {
      useFactory: (backend: MockBackend, defaultOptions: BaseRequestOptions) => {
        return new Http(backend, defaultOptions);
      },
      deps: [MockBackend, BaseRequestOptions]
    }),
    provide(AuthHttp, { useFactory: Http }),
    provide(AuthConfig, {useValue: new AuthConfig()}),
    ConnectionBackend
  ]);

But didn't had luck though.

Hey @chenkie ,
I saw that you repopen it, is it angular2-jwt issue?
I'm still not able to test my components/services that they use it :(
Here's an other example:
http://stackoverflow.com/questions/38400655/angular-2-unit-test-error-cannot-resolve-all-parameters-for-requestoptions/

I got this working using:

 beforeEach(() => {
        addProviders([
            MockService,
            MockBackend,
            BaseRequestOptions,
            {
                provide: Http,
                useFactory: (backend, options) => new Http(backend, options),
                deps: [MockBackend, BaseRequestOptions]
            },
            {
                provide: AuthHttp,
                useFactory: (http) => {
                    return new AuthHttp(new AuthConfig(), http);
                },
                deps: [Http]
            }
        ])
    })

I also made a mock service to help with injection of JwtHelper where I need it.

@drnknmstrr That is awesome. Thanks for that! Might be out of scope for this discussion but would be interested how you deal with JwtHelper?

If this is still an issue, please reopen or file a new issue.

@perrosen if you inject JwtHelper instead of newing it, you can replace it easily with a mock. Otherwise, just use it as is. If you need more help, please file a new issue.

I am still facing a problem with AuthHttp. Karma tests always succeed no matter if the expectation is wrong. It doesn't even show the console.log inside the observable.do(), so I think maybe the method is not executing. Here is my configuration and a sample test:

describe('test', () =>
 {
    let backend: MockBackend;
    let myService: MyService; 

    beforeEach( async(() =>
    {
      TestBed.configureTestingModule({
        providers: [
          MyService,
          BaseRequestOptions,
          MockBackend,
          {
              provide: Http,
              useFactory: (mockBackend: MockBackend, defaultOptions: BaseRequestOptions) => {
                return new Http(mockBackend, defaultOptions);
              },
              deps: [MockBackend, BaseRequestOptions]
          },
          {
              provide: AuthHttp,
              useFactory: (http) => {
                return new AuthHttp(new AuthConfig({
                  tokenName: 'tokenJwt',
                  tokenGetter: (() => encodeTestToken(this)),
                  globalHeaders: [{'Content-Type': 'application/json'}]
                }), http);
              },
              deps: [Http]
          },
          { provide: XHRBackend, useClass: MockBackend }
        ],
        imports: [ HttpModule],
      })
    }));

    describe('teste no metodo recuperarPF()', () =>
    {
        let fakeP: string;
        let testID : string;
        let response: Response;

        beforeEach(inject([AuthHttp, XHRBackend], (authHttp: AuthHttp, be: MockBackend) => {
          backend = be;
          myService = new MyService(authHttp);
          fakeP = retornoRPFC();

          testID = '123456789';
          let options = new ResponseOptions({status: 200, body: {data: fakeP}});
          response = new Response(options);
        }));

        it('chamada com espera de fake status(Observable.do)', async(inject([], () => {
          backend.connections.subscribe((c: MockConnection) => c.mockRespond(response));

          myService.recuperarPF(testID)
            .do(
              p => {
                console.log('HELLO'); // doesn't show anything
                expect(p._body.data).toBe(fakeP, 'should be the same');
          })
        .toPromise();
    })));
});

Thanks in advance,

Gabriel

there's no subscription to cause the .do() to do anything.

I didn't understand.

When I use the same structure for a http test, it does work.
However it doesn't work for an AuthHttp test. I don't know if I am injecting it properly or if it is a configuration issue.

For example, for a http test:

```
beforeEach(inject([Http, XHRBackend], (http: Http, be: MockBackend) => {
backend = be;
service = new LoginService(http);
fakeToken = criaToken();

  let options = new ResponseOptions({status: 200, body: {data: fakeToken}});
  response = new Response(options);
}));

it('chamada com espera de fake status(Observable.do)', async(inject([], () => {
  backend.connections.subscribe((c: MockConnection) => c.mockRespond(response));

  service.login('test', '********')
    .do(token => {
      console.log(token);
      expect(token._body.data).toBe(fakeToken, // if it was "expect(token._body.data).toBe('a'" it fails
        'should be the same');
    })
    .toPromise();
})));

```

Was this page helpful?
0 / 5 - 0 ratings

Related issues

guillaume-skwid picture guillaume-skwid  路  5Comments

wannabegeek picture wannabegeek  路  3Comments

jaumard picture jaumard  路  5Comments

nickraphael picture nickraphael  路  3Comments

UlyssesAlves picture UlyssesAlves  路  5Comments