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 parsetends 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
requireing 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
logas an argument ofdecorateLog(this is known as dependency injection) - This allows me to pass a safe
fakeLogfunction during my test, effectively testingdecorateLogin isolation - The problematic real
fancy-logis now only imported inlint.js, wheredecorateLog()is called