CommandTestFactory
To get started with the CommandTestFactory you need to make use of the createTestingCommand,
similar to TestingModule’s createTestingModule. This command can take in general module
metadata, including providers, but generally it’s pretty easy to just take in the related module and
use overrideProvider for mocking whatever providers are necessary to mock.
Mocking Commands
Normally when running a CLI you’d do something like
<cli-name> <command-name> <argument> [options], right, something like
crun run 'echo Hello World!', but that’s harder to do in a testing environment. With our
CommandTestFactory instead, we can do something like the following:
describe('Task Command', () => {
let commandInstance: TestingModule;
beforeAll(async () => {
commandInstance = await CommandTestFactory.createTestingCommand({
imports: [AppModule]
}).compile();
});
it('should call the "run" method', async () => {
const spawnSpy = jest.spyOn(childProcess, 'spawn');
await CommandTestFactory.run(commandInstance, ['run', 'echo Hello World!']);
expect(spawnSpy).toBeCalledWith(['echo Hello World!', { shell: os.userInfo().shell }]);
});
});
Aside from the Jest spies that we’re using, you’ll notice that we use the CommandTestFactory to
set up a TestingModule and use it to run a test command. We pass the run command here to match
our @Command() we already created, but because run is the default command, it can be omitted.
Then we pass in our arguments as the next array value, and any flags would be array values after it.
All of this gets passed on to the commander instance and is processed as usual.
Mocking User Input
Now this is great and all, but we also need to be able to mock user inputs, as we allow the
InquirerService to take in responses to questions. For this, we can use
CommandTestFactory.setAnswers(). We can pass an array of answers to the setAnswers method to
mock the input gained from the user.
describe('Task Command', () => {
let commandInstance: TestingModule;
beforeAll(async () => {
commandInstance = await CommandTestFactory.createTestingCommand({
imports: [AppModule]
}).compile();
});
it('should call the "run" method', async () => {
CommandTestFactory.setAnswers(['echo Hello World!']);
const spawnSpy = jest.spyOn(childProcess, 'spawn');
await CommandTestFactory.run(commandInstance, ['run']);
expect(spawnSpy).toBeCalledWith(['echo Hello World!', { shell: os.userInfo().shell }]);
});
});