Dependency injection of aurelia-authentication during testing


#1

I recently changed my app to use aurelia-authentication. This is injected normally into my services

authentication-service.ts

import { AuthService } from "aurelia-authentication";

@autoinject
export class AuthenticationService {
  constructor(private readonly authService: AuthService) { }

etc
}

authService is injected into all the classes that require it, e.g.

import { HttpClient } from "aurelia-fetch-client";
import { AuthenticationService } from "./authentication-service";

@autoinject
export class DictionaryService extends BaseFetchService<IDictionary> implements IBaseFetchService<IDictionary, IListItem> {
  
  constructor(
    http: HttpClient,
    authService: AuthenticationService,  
  ) {
    super("api/dictionary", http, authService);
  }
etc

My jest tests look like

import { HttpClient } from "aurelia-fetch-client";
import { Container } from "aurelia-framework";
import { CostingsService } from "../../src/services/costings-service";

describe("CostingsService", () => {
  let auContainer: Container;
  let sut: CostingsService;

  beforeEach(() => {
    auContainer = new Container();
    auContainer.registerInstance(HttpClient);
    sut = auContainer.get(CostingsService);
  });

While the application works perfectly, all my tests now fail with:

​​Error: Error invoking AuthService. Check the inner error for details.​​
    ​​------------------------------------------------​​
    ​​Inner Error:​​
    ​​Message: Cannot read property 'getItem' of undefined​​
    ​​Inner Error Stack:​​
    ​​TypeError: Cannot read property 'getItem' of undefined​​
    ​​    at Storage.get (C:\Visual Studio\FactoryCashFlow\FactoryCashFlow\node_modules\aurelia-authentication\dist\commonjs\aurelia-authentication.js:549:61)​​
    ​​    at new AuthService (C:\Visual Studio\FactoryCashFlow\FactoryCashFlow\node_modules\aurelia-authentication\dist\commonjs\aurelia-authentication.js:1196:43)​​
    ​​    at Object.invoke (C:\Visual Studio\FactoryCashFlow\FactoryCashFlow\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:473:12)​​
    ​​    at InvocationHandler.invoke (C:\Visual Studio\FactoryCashFlow\FactoryCashFlow\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:419:166)​​
    ​​    at Container.invoke (C:\Visual Studio\FactoryCashFlow\FactoryCashFlow\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:690:23)​​
    ​​    at StrategyResolver.get (C:\Visual Studio\FactoryCashFlow\FactoryCashFlow\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:52:36)​​
    ​​    at Container.get (C:\Visual Studio\FactoryCashFlow\FactoryCashFlow\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:617:39)​​
    ​​    at Object.invoke (C:\Visual Studio\FactoryCashFlow\FactoryCashFlow\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:467:31)​​
    ​​    at InvocationHandler.invoke (C:\Visual Studio\FactoryCashFlow\FactoryCashFlow\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:419:166)​​
    ​​    at Container.invoke (C:\Visual Studio\FactoryCashFlow\FactoryCashFlow\node_modules\aurelia-dependency-injection\dist\commonjs\aurelia-dependency-injection.js:690:23)​​
    ​​End Inner Error Stack​​
    ​​------------------------------------------------​​

I’ve tried auContainer.registerInstance(AuthService) but that doesn’t work.

Clearly I still haven’t quite grapsed how DI works with aurelia!


#2

I think the overall documentation on building out tests with plugins is poor. I can’t seem to get validation working either. I think the answer here will help me


#3
auContainer.registerInstance(HttpClient);

Can you check your code again here, to see if TS is giving any warning? registerInstance call takes 2 parameters: a key and an instance as value. What you did above is basically registering undefined as an instance of HttpClient, which I think matches pretty well with the error you logged :smile:


#4

auContainer.registerInstance(HttpClient);

Oh that has always worked brilliantly for me, because I am never interested in the results of calls to HttpClient. I’m only interested in the other methods in the class.

I just included this (as per your previous advice) to get the tests to run. Also I have never seen an error because of this.


#5

Can you check your code again here, to see if TS is giving any warning? registerInstance call takes 2 parameters: a key and an instance as value. What you did above is basically registering undefined as an instance of HttpClient , which I think matches pretty well with the error you logged :smile:

Actually it’s a bit wrong, it’s not undefined, but it will be the key itself. Sorry for that.

It’s the Authentication that requires Storge on PLATFORM.global to be setup properly that caused the issues, as you can see from here https://github.com/SpoonX/aurelia-authentication/blob/master/src/storage.js#L12

I guess you didn’t initialize platform proper before running your test, so I would suggest doing:

import { initialize } from 'aurelia-pal-browser'; // for karma

initialize();

// ... tests here

#6

Sorry - I’m lost. I’m not using karma - I’m using jest.

My jest-pretest.ts is

import { Options } from "aurelia-loader-nodejs";
import { globalize } from "aurelia-pal-nodejs";
import "aurelia-polyfills";
import * as path from "path";
Options.relativeToDir = path.join(__dirname, "unit");
globalize();

I don’t even seem to have aurelia-pal-browser installed - at least typescript is telling me it can’t find it.


#7

I see, it’s fine to use aurelia-pal-nodejs and jest. What is lacking is localStorage API for aurelia-authentication to work, for this, I would suggest you try out this work from @huochunpeng https://github.com/aurelia/cli/pull/1019 , it adds localstorage API to jsdom environement.

Can you give it a try?


#8

I had a look but was completely lost. What am I supposed to try exactly? Do I need to download a new version of something?


#9

Morning,

Tbh, I’m not sure :smile: I’ll check and put together step by step, maybe.


#10

Sorry for late reply. Try this one, easier for you https://github.com/aurelia/pal-nodejs/pull/34

You can update your package.json with

"aurelia-pal-nodejs": "huochunpeng/pal-nodejs#upgrade-jsdom",

#11

Brilliant! All working now.

Million thanks


#12

Mind my branch might break when we are ready to merge.

I checked in all dist files changes for easy testing, but I will remove them when it’s ready to merge.


#13

Do you mind posting here when you do the merge?


#14

Sure, I will let you know.