Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot mock authentication function since v6.4.0 #1679

Open
2 of 4 tasks
jscn opened this issue Sep 17, 2024 · 1 comment
Open
2 of 4 tasks

Cannot mock authentication function since v6.4.0 #1679

jscn opened this issue Sep 17, 2024 · 1 comment

Comments

@jscn
Copy link

jscn commented Sep 17, 2024

I'm using tsoa in conjunction with express and inversify and since 6.4.0 many of my tests are broken because I can no longer mock the authentication function. It's a bit convoluted (for reasons) but I'll try to describe the set up below:

My authentication logic is implemented as a method on a class that has a bunch of dependencies injected in the constructor via inversify. Since tsoa requires the authentication middleware to be a function, I have some code that rebinds and exports the relevant method on my authentication class as a function. That function is then referenced in the tsoa configuration. In my controller tests, I want to override the authentication code, and so I mock the relevant function using jest.spyOn.

This worked up until the change introduced in 0dac399 where the authentication function is rebound and typecast to a local const in the generated code. I don't understand why rebinding the function to a locally scoped const should somehow un-mock the function in question, but that appears to be what's happening.

I'm open to the idea that I'm just holding this wrong, and there may be a simpler approach that isn't vulnerable to this problem.

Sorting

  • I'm submitting a ...

    • bug report
    • feature request
    • support request
  • I confirm that I

    • used the search to make sure that a similar issue hasn't already been submit

Expected Behavior

I should be able to mock the authentication code so that I can return a valid user, throw an error, whatever.

The class that implements authentication:

@injectable()
export class TsoaAuthentication {
  constructor(@inject(SomeService) private readonly service: SomeService ) {}

  async authenticate(request: ExpressRequest, securityName: string, scopes?: string[]) {
    // call the service, do the checks, return the user or throw.
  }
}

The file that makes the authentication code conform to the API described in https://tsoa-community.github.io/docs/authentication.html:

import { TsoaAuthentication } from './security';
import { iocContainer } from '../ioc/apiContainer';

const tsoaAuthentication = iocContainer.get(TsoaAuthentication);

/**
 * NB: The name of this export must be `expressAuthentication`.
 * See https://tsoa-community.github.io/docs/authentication.html
 */
export const expressAuthentication = tsoaAuthentication.authenticate.bind(tsoaAuthentication);

The test file:

import * as TsoaAuthenticationModule from '../../../authentication';

describe('the controller', () => {
    const mockSecurityMiddleware = jest
        .spyOn(TsoaAuthenticationModule, 'expressAuthentication')
        .mockResolvedValue(authenticatedUser);

   it('works', async () => {
    // ... test code relying on the authentication function to return authenticatedUser
  })
}

Current Behavior

The tests fail because the original implementation of the authentication function is executed at runtime, instead of the mock/spy. I know that it's related to the aforementioned commit, because I can fix the issue by opening the generated routes, commenting out the relevant line, and importing the original authentication function with the new name:

routesGen.ts:

import { expressAuthentication as expressAuthenticationRecasted  } from './../authentication';
...
// const expressAuthenticationRecasted = expressAuthentication as (req: ExRequest, securityName: string, scopes?: string[], res?: ExResponse) => Promise<any>;

Possible Solution

I don't understand what's happening well enough to suggest a solution

Context (Environment)

Version of the libraries:

  • @tsoa/runtime: 6.4.0
  • @tsoa/cli: 6.4.0
  • jest: 29.5.0
  • inversify: 6.0.1

Version of NodeJS: v18.20.2

Copy link

Hello there jscn 👋

Thank you for opening your very first issue in this project.

We will try to get back to you as soon as we can.👀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant