I'm already familiar with unit testing, but there are gaps in my knowledge.
I like to test real code, so I have been trying to test some of my custom Gulp modules.
Module:
// gulp-modules/helpers.js
// the module I want to test
// it imports two dependencies
// removing these two imports and their uses prevents the Cypress error
import color from 'gulp-color';
import log from 'fancy-log';
const sentenceToCamelCase = ( sentence ) => { ... }
Test:
// cypress/integration/spec.js
// import the module I want to test
import { sentenceToCamelCase } from '../../gulp-modules/helpers';
Cypress:
Uncaught Error: Unable to parse
I'm currently unable to test my Gulp modules in Cypress, because those modules have dependencies, which are imported using ES6 module import
.
It feels like this should be a common problem, but after much Googling the closest answers I have are:
The error
Uncaught Error: Unable to parse
tends to come from something the parser does not understand. It is possible that Cypress or what it is running on does not supportimport
.
- (answer to question on Wes Bos ES6 Slack channel)
or
I read an article about rewiremock
but it too fails, before I even call rewiremock
:
RewireMock config:
// rewiremock.js
import rewiremock from 'rewiremock';
// import rewiremock from '../../node_modules/rewiremock/lib/index.js'; // also fails
// settings
rewiremock.overrideEntryPoint( module ); // this is important
export { rewiremock };
Test:
// spec.js
import rewiremock from '../helpers/rewiremock';
Cypress:
Uncaught TypeError: require.resolve is not a function
So with more Googling, I'm now watching Fun Fun Function's Unit testing in JavaScript and it is very good.
And I learned about Quokka,
a rapid prototyping playground
which is a fun way to test code in the same file that it is authored in.
if ( !decorateLog( {
textstring: 'A pass'
} ).match( /^\[32m✔ A pass\[0m$/ ) ) {
throw new Error( 'does not match' );
}
And for some reason my import is no longer throwing errors in Cypress. Perhaps the fancy-log
plugin was incompatible with ES6/Cypress?
Takeouts:
- a test runner functions like a linter for the code logic
- unit tests/assertions are like a series of examples, of how to call the function under test
- 'dependency injection' involves passing a dependency into a function, rather than
require
ing it first - a Quokka sandbox allows us to test that APIs work as we assume in our mocks, or adjust our mocks accordingly
After watching the second video on Mocking,
- I removed
import log from 'fancy-log'
fromdecorate-log.js
(which is the file imported into my test) - I added
log
as an argument ofdecorateLog
(this is known as dependency injection) - This allows me to pass a safe
fakeLog
function during my test, effectively testingdecorateLog
in isolation - The problematic real
fancy-log
is now only imported inlint.js
, wheredecorateLog()
is called