-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Command not unit test friendly #438
Comments
You can use proxyquire to control it, or . . . if you don't like stubs (depends on your school of thought for tdd), use clear-require to reset the state of the module and then require it again. |
It would be nice to have the library stop using globals, and allow things like "log" and "error" to be passed as options. Also consistent usage of console.log vs process.stdout.write (always using console.log seems like the way to go). I've had a pretty miserable time trying to unit test my cli w/ code coverage. I ended up needing to use spawn() to write my tests (which works okay), but I haven't gotten coverage w/ istanbul working yet. When I tried using sinon to override things like process.exit, and process.stdout.write, I entered the rabbit hole. Started working on a PR here to allow all globals to be passed as params, but that didn't seem like it would actually help in the end. Hopefully someone here can post some links to successful cli unit testing with code coverage! I know I'd be interested in other examples (my approach isn't the best- and other examples I've tried never work in my codebase)... |
Turns out that the solution already exists. The Command class can easily be imported and instantiated: import {Command} from "commander";
const commander = new Command();
// now use the local instance as you would use the global one... It simply doesn't seem to be documented anywhere besides the code itself. I ran into this problem once again when I was upgrading to Mocha 3.x. Suddenly all my tests against commander started to fail as Mocha was also using the global commander instance and the command line options my library was using got mixed together with command line options of Mocha. Rewriting my CLI to instantiate separate Command class solved the whole problem easily. |
You can use |
@vanesyan thanks for that i've been puzzled for a while! Worked like a charm. |
Are there any unit testing examples? Haven't been able to find any. |
There are the unit tests for Commander itself. Most of them predate the "new commander.Command" style but these two got updated recently. |
@shadowspawn Yeah saw those, thanks. I can't find any way of testing commands that have prompts in them though, is that even possible? |
What prompts? I have seen Commander did once support prompts (e.g. #163) but not since I started using it, so that might be another library. |
I'm using this https://www.npmjs.com/package/prompt to prompt for login details for the database for example. So the flow would be:
Step 1 and 3 are simple enough but the prompt bit I'm unsure of how to achieve. |
Sounds like a question for Prompt rather than Commander! But as a suggestion, you could read the login details from environment variables for testing purposes to avoid the interactive prompt. |
Hmm not a half bad idea that. Would require some code tweaks but should be easy enough, thanks :) |
I a lot of unit tests for my code to test parsing the command line. Commander instantiates on the require('command') statement and is cached. My unit tests do not have a way to reset commander back to its initial state. Many of my unit tests fail because values from the previous unit tests inside of commander carry over.
can we get a way to create a new Commander() each time for unit testing. Or at least a function like commander.reset() to flush the previous state of commander between unit tests?
Thanks
The text was updated successfully, but these errors were encountered: