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 }]);
});
});