Closed bySabi closed 8 years ago
td.reset
can't know what you're overriding unless you use td.replace
to allow it the ability to reassign it. Therefore, what you have:
console.error = td.function('console.error');
will not be resettable because td.js can't know what you assigned that td to. However, this should work:
td.replace(console, 'error')
In any case you should consider wrapping the console with a function you do own. See this article for more details: https://github.com/testdouble/contributing-tests/wiki/Don%27t-mock-what-you-don%27t-own
@searls td.replace
and td.reset
works very well, thanks.
One more thing. Is any problem with this console.error
"Warnings" spy approach?. I read that wiki again to day but still not figure out how and why wrapping console
with my own function could be helpme. Any advice?
In short, because the purpose of test double libraries is not to "fake stuff out so that hard-to-test things become testable". The purpose of test double libraries is to help you discover that hard-to-test things could be better-designed.
In this case, your code depends on a built-in host function that you don't control (console.error
), which means you can't introspect/wrap/tap into it. You can indeed just fake it out like you did in this case, but what if the console.error
was hard to mock or replace? (Indeed, this is a good example, because many hosts like MSIE don't take kindly to reassigning the console
functions.) Attempting to deal with hard-to-use or hard-to-mock APIs by way of increasingly clever test double strategies is a useless outlet for the pain.
Instead, test double aficionados like myself will encourage you to wrap all third party libraries you use where you'd want to mock them out. So, in this case, I would write my own module like this:
module.exports = {
error: console.error
}
And maybe name it wrap/console
or adapter/log
or something and then replace that module with td.replace
. That way if I ever need to change that API or its implementation, perhaps due to some pain in testing it, I'm already well-positioned to make those changes.
Test doubles and outside-in testing is a highly-opinionated commentary on how we design our code and separate the code we own from the code we don't. Very few people really think very hard about this in practice, because the universe of people who care about nuanced software design is tiny and the universe of people who just need a library to fake stuff out is massive.
The purpose of test double libraries is to help you discover that hard-to-test
things could be better-designed.
I ended removing all console.error
based test :-). And looking for better checks. React throw 'Warnings' only on dev mode. In production console.error
base test will fail.
Very few people really think very hard about this in practice,
because the universe of people who care about nuanced software design
is tiny and the universe of people who just need a library to fake stuff out is massive.
I´m a unit test newbie but choose learn and use: tape/testdouble for React test beside massive choosed jasmine/sinon cause I can see from where test code come and I feel more in-control and less "bewitched".
Thanks for In short, ...
words :-). Your advice was really useful.
I have working test with React, Enzyme, Tape and TestDouble here: https://github.com/bySabi/react-scrollaware/blob/master/test/scrollaware-test.js ... any suggestion from you is really welcome. Only If you have the time to take a look, of course.
Thanks very much for the kind words bySabi. If you get the time to read more of our testing wiki or about test double's motivations, please let me know if they help.
Feel free to open more questions if you have them.
I had been testing some React components with enzyme and tape.
I testdouble
console.error
function in order of capture React consoleWarning:
and my custom generatedWarning:
too:Ex:
console.error
"spying?" works very good but on next unit test console.error is still mocked. I suppose thattd.reset()
will get it back but is not happend. That´s was I addconsoleError
, see/* .. */
comments.td.reset() is working right?
Thanks for the hard work on testdouble is very easy to use.