docs.nestjs.com
docs.nestjs.com copied to clipboard
suggestion: add recipe for @automock/jest for automocking capabilities
I'm submitting a:
- [ ] Regression
- [ ] Bug report
- [x] Feature request
- [x] Documentation issue or request (new chapter/page)
- [ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Hi,
In this pull request (https://github.com/nestjs/nest/pull/6277) there is a discussion regarding auto mocking capabilities using the testing module which has been created by @jmcdo29. I added a comment there back at the time which describes another solution for auto mocking capabilities for (solitary) unit tests.
Before I create a pull request to NestJS docs, I thought it worth presenting the package here and having a discussion about it.
The package is called "@automock/jest" (here is a link). It suggests a simple mechanism (using reflection) for auto mocking the class constructor's dependencies (without loading the whole module). here is a short example for the sake of the discussion:
Consider the following provider/class:
@Injectable()
export class SomeService {
public constructor(
private readonly logger: Logger,
private readonly catsService: CatsService,
private readonly userService: UserService,
private readonly featureFlagService: FeatureFlagService,
) {}
public async doSomethingNice() {
if (this.featureFlagService.isFeatureOn()) {
const users = await this.userService.getUsers('https://example.com/json.json');
this.logger.log(users);
return users;
}
}
}
And now look the spec file:
import { Spec } from '@automock/jest';
import Mocked = jest.Mocked;
describe('SomeService Unit Test', () => {
let someService: MainService;
let logger: Mocked<Logger>;
let userService: Mocked<UserService>;
const USERS_DATA = [{ name: 'user', email: '[email protected]' }];
beforeAll(() => {
const { unit, unitRef } = Spec.create(MainService)
.mock(FeatureFlagService)
.using({ isFeatureOn: () => Promise.resolve(true) })
.compile();
someService = unit;
userService = unitRef.get(UserService);
});
describe('When something happens', () => {
beforeAll(() => (userService.getUsers.mockResolvedValueOnce(USERS_DATA));
test('then check something', async () => {
await service.doSomethingNice();
expect(logger.log).toHaveBeenCalledWith(USERS_DATA);
});
});
});
It also works with custom tokens (when you have an interface and not a concrete class). As said, because the dependencies are being mocked (actually stubbed) automatically, and everything is replaced - there is no need to load the whole module, thus, the spec runs really (really) fast and it's very easy to write.
I would love to hear what are you guys think (CC: @jmcdo29)
Thanks!
@jmcdo29 do you want to create a PR?
I think this looks like a really cool package. I think we could at least open a PR for a new Recipe showing it off. If nothing else I'd love to see a PR against my testing-nestjs repo to show it off to others as well, similarly to how I've integrated @golevelup/ts-jest. Really love seeing all this tooling showing up!
Thank you @jmcdo29! Really trying to improve Nest and TypeScript ecosystem so we can all enjoy some great tools :) I will create a PR at testing-nestjs repository and we'll continue from there!
This issues we could close it since there is a PR here, right ?