NestJS not injecting mocked module unless provider tokens are used

I’m writing unit tests for a sandbox project to test a few things in NestJS. I’ve run into an issue where a class that takes an injected service (authService) is showing up as undefined when being mocked in unit tests. However, the moment I inject it using provider tokens, the service seems to get mocked properly and doesn’t show up as undefined.

I imagine that this issue is with me not making the mock module properly because BOTH approaches work just find in practice (outside of unit tests). It’s only during testing that I can only mock using provider tokens otherwise the authService in AuthImplementation shows up as undefined.

Here is my module – auth.module.ts

@Module({
    imports: [DatabaseModule],
    controllers: [AuthController],
    providers: [
        {
            provide: 'UserRepository',
            useFactory: (databaseAdapterService: DatabaseAdapterService) =>
                databaseAdapterService.getUserRepository(),
            inject: [DatabaseAdapterService],
        },
        {
            provide: AuthService,
            useFactory: (userRepository: UserRepository) => {
                return new AuthService(userRepository);
            },
            inject: ['UserRepository'],
        },
        {
            provide: AuthImplementation,
            useFactory: (authService: IAuthService) =>
                new AuthImplementation(authService),
            inject: [AuthService],
        },
    ]
})

The AuthImplementation class is the following – auth.implementation.ts

import { Inject } from '@nestjs/common';
import { User } from 'src/domain/entities/user.entity';
import { AUTH_SERVICE, IAuthService } from 'src/domain/ports/auth-service.interface';

export class AuthImplementation {
    constructor(@Inject(AUTH_SERVICE) private readonly authService: IAuthService) { }
    
    // This approach, without the provider token, fails the unit tests because
    // authService shows up as undefined when mocked
    // constructor(private readonly authService: IAuthService) { }

    async register(username: string, password: string): Promise<User> {
        return this.authService.register(username, password);
    }

    async login(username: string, password: string): Promise<User | null> {
        return this.authService.login(username, password);
    }
}

And the unit test that only works when the provide field for the mockAuthService is defined with a provider token looks as the following – auth.implementation.spec.ts

describe('AuthImplementation', () => {
    let authImplementation: AuthImplementation;
    let mockAuthService: jest.Mocked<IAuthService>;

    beforeEach(async () => {
        mockAuthService = {
            register: jest.fn(),
            login: jest.fn(),
        };

        const module: TestingModule = await Test.createTestingModule({
            providers: [
                AuthImplementation,
                {
                    // NOTE: This approach does not work
                    //provide: AuthService,

                    // NOTE: This works just fine
                    provide: AUTH_SERVICE,
                    useValue: mockAuthService,
                },
            ],
        }).compile();

        authImplementation = module.get<AuthImplementation>(AuthImplementation);
    });

    describe('register', () => {
        it('should register a user and return the user object', async () => {
            const username = 'testuser';
            const password = 'testpass';
            const mockUser = new User(new ObjectId(), username, password);

            mockAuthService.register.mockResolvedValue(mockUser);

            const result = await authImplementation.register(username, password);

            expect(mockAuthService.register).toHaveBeenCalledWith(username, password);
            expect(result).toBe(mockUser);
        });
    });

So my question is that, instead of having to define a provider token such as export const AUTH_SERVICE = Symbol('AUTH_SERVICE'); and using it when injecting the auth service, is there any way to directly refer to the AuthService in the testing module? Why can I get away with:

provide: AUTH_SERVICE,

but not

provide: AuthService,

which yields as undefined in the AuthImplementation when logging authService?