We have trying to do a test with loopback. The test involve to call the google API and we want to mock it with Sinon.
The Controller:
[...]
In the constructor:
@inject('services.OAuth2Service')
private oauth2Service: OAuth2Service
[...]
In the endpoint:
@post('/user-accounts/authenticate/oauth2', {
async authenticateOauth2(
@requestBody() oauthRequest: OAuthId,
@inject(RestBindings.Http.REQUEST) _req: Request,
): Promise<AccessToken> {
const email = await this.oauth2Service.getOAuth2User(oauthRequest); // The method to mock.
....
}
The test:
it('oauth2 authentication with google', async () => {
//Create a spy for the getOAuth2User function
inject.getter('services.OAuth2Service');
var oauth2Service: OAuth2Service;
var setOauthSpy = sinon.spy(oauth2Service, "getOAuth2User"); // Error: Variable 'oauth2Service' is used before being assigned
const res = await client
.post('/user-accounts/authenticate/oauth2')
.set('urlTenant', TEST_TENANT_URL1A)
.set('userType', TEST_USERTYPE1)
.send({
code: TEST_GOOGLE_AUTH2_CODE_KO,
providerId: TEST_GOOGLE_PROVIDER,
redirectUri: TEST_GOOGLE_REDIRECT_URI,
})
.expect(401);
expect(res.body.error.message).to.equal('The credentials are not correct.');
setOauthSpy.restore();
});
How can we test this method? how can we test an endpoint who involves an injection in the constructor in loopback? Please, we need any help.
I see two options:
Before running the test, create a loopback context, bind your stub to "services.OAuth2Service"
and use that context to create the controller you want to test.
default value (probably not what you want)
In the place where you use @inject
, you provide a default value (and possibly indicate the dependency is optional), e.g. like this:
@inject('services.OAuth2Service', { optional: true })
private oauth2Service: OAuth2Service = mockOAuth2Service,
In other places this might come handy for you, but you should probably not pollute your default production code with defaults to test objects.