I've been trying to get Jest working with my react native project without much luck. Seems most threads are hacked solutions to get things up and running and I can't seem to get over the last hurdle I'm facing.
Problem
I'm getting the following error when trying to run the following piece of code. If I mock react-native inside of the jestSupport/env.js file I can get past the error but obviously I cannot use any of the structures such as AsyncStorage to actually test my code (as I'll only have the mocked functionality).
Question
Does anyone have any suggestions on how to solve this problem?
At this stage I'm willing to try anything up to and including scrapping everything test related that I have and trying again. If that were the case, I'd need some set of guidelines to follow as the React Native docs are horribly out of date regarding Jest and I'm relatively new to the React scene.
Error
Runtime Error
Error: Cannot find module 'ReactNative' from 'react-native.js'
at Runtime._resolveNodeModule (/Users/Yulfy/Downloads/COMPANY-Mobile/node_modules/jest-cli/src/Runtime/Runtime.js:451:11)
at Object.<anonymous> (/Users/Yulfy/Downloads/COMPANY-Mobile/node_modules/react-native/Libraries/react-native/react-native.js:181:25)
at Object.<anonymous> (/Users/Yulfy/Downloads/COMPANY-Mobile/network/connections.js:8:18)
Test Code
jest.unmock('../network/connections');
import Authorisation from '../network/connections';
describe('connections', () => {
it('Should store and retrieve a mocked user object', () => {
Auth = new Authorisation();
const TEST_STRING = "CONNECTION TEST PASS";
var userObj = {
test_string: TEST_STRING
};
Auth._localStore(userObj, (storeRes) => {
Auth._localRetrieve((retRes) => {
expect(retRes.test_string).toEqual(TEST_STRING);
});
});
});
});
connection.js
/*
* All returns should give the following structure:
* {isSuccess: boolean, data: object}
*/
import React, { Component } from 'react';
import { AsyncStorage } from 'react-native';
const Firebase = require('firebase');
const FIREBASE_URL = 'https://COMPANY-test.firebaseio.com';
const STORAGE_KEY = 'USER_DATA';
class Authorisation{
_ref = null;
user = null;
constructor(){
}
getOne(){return 1;}
_setSystemUser(userObj, authObj, callback){
var ref = this.connect();
if(ref === null){
callback({isSuccess:false, data:{message:"Could not connect to the server"}});
}
ref = ref.child('users').child(authObj.uid);
ref.once("value", function(snapshot){
if(snapshot.exists()){
callback({isSuccess:false, data:{message:"Email is currently in use"}});
return;
}
ref.set(userObj, function(error){
if(error){
callback({isSuccess:false, data:error});
}else{
callback({isSuccess:true, data:authObj});
}
});
});
}
_localStore(userObj, callback){
AsyncStorage.setItem(STORAGE_KEY, userObj, (error) => {
console.log("_localStore::setItem -> ", error);
if(error){
callback({
isSuccess:false,
data:'Failed to store user object in storage.'
});
}else{
callback({
isSuccess:true,
data: userObj
});
}
});
}
_localRetrieve(callback){
AsyncStorage.getItem(STORAGE_KEY, (error, res) => {
console.log("_localStore::getItem:error -> ", error);
console.log("_localStore::getItem:result -> ", res);
if(error){
callback({
isSuccess:false,
data:error
});
}else{
callback({
isSuccess: true,
data: res
});
}
});
}
connect(){
if(this._ref === null){
_ref = new Firebase(FIREBASE_URL);
}
return _ref;
}
getUser(){
}
isLoggedIn(){
}
registerUser(userObj, callback){
var ref = this.connect();
if(ref === null){
callback({isSuccess:false, data:{message:"Could not connect to the server"}});
}
var that = this;
ref.createUser({
email: userObj.username,
password: userObj.password
}, function(error, userData){
if(error){
callback({isSuccess:false, data:error});
return;
}
var parseObj = {
email: userObj.username,
fullName: userObj.fullName
};
that.loginUser(parseObj, function(res){
if(res.isSuccess){
that._setSystemUser(parseObj, res.data, callback);
}else{
callback(res);//Fail
}
});
});
}
loginUser(userObj, callback){
var ref = this.connect();
if(ref === null){
callback({isSuccess:false, data:{message:"Could not connect to the server"}});
}
ref.authWithPassword({
email: userObj.email,
password: userObj.password
}, function(error, authData){
if(error){
callback({isSuccess:false, data:error.message});
}else{
callback({isSuccess:true, data:authData});
}
});
}
}
export default Authorisation;
If you've read this far, thanks for your time!
-Yulfy
TL;DR
I have a working example of Jest running with the latest version React Native (v0.28.0) in this GitHub Repo.
-
After investigating this problem for quite some time, I finally found the solution.
There are a few online examples of React Native applications that are integrated with Jest, but you can't simply copy and paste the code into your codebase and expect it to work, unfortunately. This is because of RN version differences.
Versions of React Native prior to v0.20.0 contained a .babelrc file in the packager (node_modules/react-native/packager/react-packager/.babelrc) that some online examples directly include it in their package.json. However, versions v0.20.0 and up changed to no longer include this file which means that you can no longer attempt to include it. Because of this, I recommend using your own .babelrc file and definte your own presets and plugins.
I don't know what your package.json file looks like, but it's an incredibly important piece to solving this problem.
{
"name": "ReactNativeJest",
"version": "0.0.1",
"jest": {
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
"unmockedModulePathPatterns": [
"node_modules"
],
"verbose": true,
"collectCoverage": true
},
"scripts": {
"test": "jest"
},
"dependencies": {
"react": "^15.1.0",
"react-native": "^0.27.2"
},
"devDependencies": {
"babel-core": "^6.4.5",
"babel-jest": "^12.1.0",
"babel-plugin-transform-regenerator": "^6.0.18",
"babel-polyfill": "^6.0.16",
"babel-preset-react-native": "^1.9.0",
"babel-types": "^6.1.2",
"chai": "^3.5.0",
"enzyme": "^2.3.0",
"jest-cli": "^12.1.1",
"react-addons-test-utils": "^15.1.0",
"react-dom": "^15.1.0"
}
}
The other important piece is mocking React Native. I created a __mocks__/react-native.js file that looks like this:
'use strict';
var React = require('react');
var ReactNative = React;
ReactNative.StyleSheet = {
create: function(styles) {
return styles;
}
};
class View extends React.Component {}
class Text extends React.Component {}
class TouchableHighlight extends React.Component {}
// Continue to patch other components as you need them
ReactNative.View = View;
ReactNative.Text = Text;
ReactNative.TouchableHighlight = TouchableHighlight;
module.exports = ReactNative;
By monkey patching the React Native functions like this, you can successfully avoid the weird Jest errors you get when trying to run your tests.
Finally, make sure you create a .babelrc file in your project's root directory that has, at the very least, these following lines:
{
"presets": ["react-native"],
"plugins": [
"transform-regenerator"
]
}
This file will be used to tell babel how to correctly transform your ES6 code.
After following this setup, you should have no problems running Jest with React Native. I am confident that a future version of React Native will make it easier to integrate the two frameworks together, but this technique will work perfectly for the current version :)
EDIT
Instead of manually mocking the ReactNative elements in your __mocks__/react-native.js file, you can use the react-native-mock library to do the mocking for you (make sure to add the library to your package.json file):
// __mocks__/react-native.js
module.exports = require('react-native-mock');
I updated my GitHub Repo example to demonstrate this method.
Did you tried to mock react-native inside of test file?
It works fine for my test case:
jest.dontMock(`../my-module-that-uses React-native.AsyncStorage`);
jest.setMock(`react-native`, {
AsyncStorage: {
multiGet: jest.fn(),
},
});
const ReactNative = require(`react-native`);
const {AsyncStorage, } = ReactNative;
const myModule = require(`../my-module-that-uses React-native.AsyncStorage`);
// Do some tests and assert ReactNative.AsyncStorage.multiGet calls
Related
I have the cypress with cucumber-step-definition library.
I tried running the feature file and it doesn't work.
package.json
"devDependencies": {
"cypress": "^9.6.1",
"cypress-cucumber-preprocessor": "^4.3.1"
},
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": false,
"stepDefinitions": "cypress/integration/**/"
}
}
plugin/index.js
const cucumber =require('cypress-cucumber-preprocessor').default
module.exports = (on, config) => {
on('file:preprocessor',cucumber())
}
cypress/integration/page-step/login-step.js
import {Given,When,Then, And} from "cypress-cucumber-preprocessor/steps";
Given(/^I login to the app$/, function () {
});
Then(/^I see login on the account$/, function () {
});
cypress/integration/Login.feature
Feature: User buy a product on the website
Scenario: Buying a grocery with a proper test
Given I login to the app
Then I see login on the account
Don't know the issue as It happened to me as well. I tired this in my plugin and then it works.
/**
* #type {Cypress.PluginConfig}
*/
// eslint-disable-next-line no-unused-vars
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}
const cucumber = require('cypress-cucumber-preprocessor').default
module.exports = (on, config) => {
on('file:preprocessor', cucumber())
}
Hey I am playing around with web3 inside react as a client application (using vite react-ts) and trying to call web3.eth.net.getId() but this will throw me an error that callbackify is not a function I digged a little and found an old issue on the github which states that older versions of Nodejs.util (prior version 0.11) didn't have this function. So I checked the package.json where the error occurs (web3-core-requestmanager) it has "util":"^0.12.0", so callbackify should be available.
In fact when I am looking at their imports, they seem to be able to import it:
(following code is ./node_modules\web3-core-requestmanager\src\index.js
const { callbackify } = require('util');
but when they want to use it, callbackify is undefined
//RequestManager.prototype.send function
const callbackRequest = callbackify(this.provider.request.bind(this.provider));
I tried to play around with the dependencies and tried different versions of web3.js (1.7.3; 1.6.0; 1.5.1) all of them had the same util dependency (0.12.0).
My code in all this matter looks like this:
class Blockchain {
public blockchainBaseUrl: string;
public web3;
public provider;
public account: string = '';
public contract: any;
constructor() {
if (process.env.REACT_APP_BLOCKCHAIN_BASE_URL === undefined) {
throw new Error('REACT_APP_BLOCKCHAIN_BASE_URL is not defined');
}
this.provider = window.ethereum;
if (this.provider === undefined) {
throw new Error('MetaMask is not installed');
}
this.setUpInitialAccount();
this.addEthereumEventListener();
this.blockchainBaseUrl = process.env.REACT_APP_BLOCKCHAIN_BASE_URL;
this.web3 = new Web3(Web3.givenProvider || this.blockchainBaseUrl);
this.setContract();
}
async setContract() {
// error comes from the next line
const networkId = await this.web3.eth.net.getId();
this.contract = new this.web3.eth.Contract(
// #ts-ignore
Token.abi,
// #ts-ignore
Token.networks[networkId].address
);
}
}
I also was told that I should simply add a .catch() to web3.eth.net.getId() but this did nothing. Am I doing something wrong or is this a dependency problem? If anyone could point me in the right direction I would really appreciate it. Do I need to expose the util API to the browser somehow? To me, it seems that the API is simply not available.
This is should be the relevant part of my vite.config.ts:
import GlobalsPolyfills from '#esbuild-plugins/node-globals-polyfill';
import NodeModulesPolyfills from '#esbuild-plugins/node-modules-polyfill';
import { defineConfig } from 'vite';
import react from '#vitejs/plugin-react';
export default defineConfig({
plugins: [
react(),
],
optimizeDeps: {
esbuildOptions: {
plugins: [
NodeModulesPolyfills(),
GlobalsPolyfills({
process: true,
buffer: true,
}),
],
define: {
global: 'globalThis',
},
},
},
});
Here is my complete vite config
https://pastebin.com/zvgbNbhQ
Update
By now I think that I understand the issue - it seems that it is a VIte-specific problem and I need to polyfill the NodeJs.util API. I am already doing this (at least I thought). Perhaps someone can provide some guidance on what I am doing wrong with my config?
Update 2
I actually have now the util API inside the browser, but it is still giving me the same error. This is my new config:
https://pastebin.com/mreVbzUW I can even log it out:
Update 3
SO I am still facing this issue - I tried a different approach to polyfill I posted the update to the github issue https://github.com/ChainSafe/web3.js/issues/4992#issuecomment-1117894830
Had similar problem with vue3 + vite + we3
It's started from errors: process in not defined than Buffer is not defined and finally after I configure polyfill I came to callbackify is not defined
Did a lot of researches and finally solved this issue with next trick:
Rollback all polyfill configurations
Add to the head html file
<script>window.global = window;</script>
<script type="module">
import process from "process";
import { Buffer } from "buffer";
import EventEmitter from "events";
window.Buffer = Buffer;
window.process = process;
window.EventEmitter = EventEmitter;
</script>
vite.config.ts
import vue from '#vitejs/plugin-vue'
export default {
resolve: {
alias: {
process: "process/browser",
stream: "stream-browserify",
zlib: "browserify-zlib",
util: 'util'
}
},
plugins: [
vue(),
]
}
add these dependencies browserify-zlib, events, process, stream-browserify, util
Source https://github.com/vitejs/vite/issues/3817#issuecomment-864450199
Hope it will helps you
The React Context API allows me to place the logic for the app state in one place (and avoid redux). Right now it looks like this
// Using the Context API used in react 16.3 - https://www.youtube.com/watch?v=XLJN4JfniH4
const { Provider, Consumer: ContextConsumer } = React.createContext()
class ContextProvider extends Component {
...// lot of functions ...
render() {
return (
<Provider
value={{
...this.state,
getDose: this.getDose,
getDoseRange: this.getDoseRange,
setDose: this.setDose,
checkIN: this.checkIN,
checkOUT: this.checkOUT,
getFalsifiedDrug: this.getDefaultproductData,
updatePrescriptionDose: this.updatePrescriptionDose,
}}
>
{this.props.children}
</Provider>
)
}
}
module.exports = { ContextConsumer, ContextProvider }
Entire code can be found here.
What's the best practice to build jest tests that allows me to test the functions and don't mess up the state?
(Would like to avoid using Enzyme (developed by AirBnB) - since AirBnB officially gave up using React Native)
Example
How do I make a test that confirms that when I call setDose(2) that the productData.dose was changed from "5 mg" and now equals "2 mg. But then set the state back to "5 mg" for the other test.
BONUS INFO
I'm having some trouble getting jest to work with me (so I can try out the suggested solutions)
package.json
{
"main": "node_modules/expo/AppEntry.js",
"private": true,
"scripts": {
"test": "jest --watchAll"
},
"dependencies": {
"#expo/samples": "2.1.1",
"crypto-js": "^3.1.9-1",
"date-fns": "^1.29.0",
"expo": "^28.0.0",
"invert-color": "^1.2.3",
"lodash": "^4.17.10",
"react": "16.3.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-28.0.0.tar.gz",
"react-native-qrcode": "^0.2.6",
"react-native-slider": "^0.11.0",
"react-native-switch": "^1.5.0",
"react-navigation": "2.3.1",
"whatwg-fetch": "^2.0.4"
},
"devDependencies": {
"babel-eslint": "^10.0.1",
"babel-preset-expo": "^5.0.0",
"eslint": "^5.16.0",
"eslint-config-codingitwrong": "^0.1.4",
"eslint-plugin-import": "^2.17.2",
"eslint-plugin-jest": "^22.5.1",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-react": "^7.13.0",
"jest-expo": "^32.0.0",
"react-native-testing-library": "^1.7.0",
"react-test-renderer": "^16.8.6"
},
"jest": {
"preset": "jest-expo"
}
}
It just throws this at me
> # test /Users/norfeldt/Desktop/React-Native/MedBlockChain
> jest --watchAll
● Validation Error:
Module react-native/jest/hasteImpl.js in the haste.hasteImplModulePath option was not found.
<rootDir> is: /Users/norfeldt/Desktop/React-Native/MedBlockChain
Configuration Documentation:
https://jestjs.io/docs/configuration.html
npm ERR! Test failed. See above for more details.
I have tried things like
rm -rf node_modules/ yarn.lock package-lock.json && npm install
You could make use of react-test-renderer which you're already using in your project specs. What you need is to call testRenderer.getInstance() => check current state => invoke some methods you need to test => check updated state:
import React from "react";
import { create } from "react-test-renderer";
import { ContextProvider } from "../Context";
describe("ContextProvider", () => {
test("it updates dose correctly", () => {
const component = create(<ContextProvider />);
const instance = component.getInstance();
expect(instance.getDose()).toBe(5);
expect(instance.state.productData.dose).toBe("5 mg");
instance.setDose(2);
expect(instance.getDose()).toBe(2);
expect(instance.state.productData.dose).toBe("2 mg");
});
test("it updates something else correctly", () => {
// ...
});
});
State for other tests won't be affected.
The only thing I needed to make this work with your repo is to npm install whatwg-fetch#2.0.4 --save as described here. Hope this helps.
UPDATE
Even though this is supposed to be another question and the obvious solution is to create a new rn project and copy you code in it, but here is what I've done to fix jest errors on your code:
1) Make versions match (as described in the comments...):
"expo": "^32.0.0",
"jest-expo": "^32.0.0",
// and maybe even
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
2) To fix an error
api.caller is not a function
use babel.config.js as described here:
module.exports = function(api) {
api.cache(true);
return {
presets: ["babel-preset-expo"],
env: {
development: {
plugins: ["transform-react-jsx-source"]
}
}
};
};
3) Use yarn due to this
If you are looking for a replacement for Enzyme, I think you should look here: https://callstack.github.io/react-native-testing-library/
That library will allow you to use the update function provided to change the values you are testing, then change them back.
Great library for React Native - the getting started page says it all. If you are interested in some code to help you get started I can work something up as well.
I suggest that you only unit-test your logic and consider avoiding component tests altogether in this case.
You can extract your methods into a "Presenter" to process your data and only test this logic. With this approach it's easy to test the presenter which has a pure input/output logic.
The presenter, for example, can look like this:
// DosePresenter.js
const processDose = (value, productData) => {
productData.dose = value.toFixed(0) + productData.dose.replace(/[\d\.]*/g, '')
productData.productionTime = Conventions.datetimeStr();
productData.hashSalt = this.makeHashSalt();
return {productData, productDataHash: getHashOfproductData(productData)};
};
module.exports = {
processDose
};
The usage:
// Context.js
import * as DosePresenter from './DosePresenter';
const setDose = (value) => this.setState(DosePresenter.processDose(value, {...this.state}));
Now it should be easier to test the logic:
// DosePresenter.test.js
describe('DosePresenter tests', () => {
let uut;
beforeEach(() => {
uut = require('./DosePresenter');
});
it('should process a dose', () => {
const value = 10;
const productData = {};
expect(uut.processDose(value, productData)).toEqual(...);
});
};
Is it possible to use Jest with multiple presets, say jsdom and react-native?
I'd like to test a React component that can work both on Web and in a React Native environment. The problem is that the component may use either React Native libraries or some document's methods.
When I run some tests, jest replies:
Cannot find module 'NetInfo' from 'react-native-implementation.js'
When I try to add
"jest": {
"preset": "react-native"
}
to package.json, I get:
ReferenceError: window is not defined
Presets are just plain Javascript objects, so in many circumstances you may simply merge them. For example, that's how I'm enabling ts-jest and jest-puppeteer simultaneously:
const merge = require('merge')
const ts_preset = require('ts-jest/jest-preset')
const puppeteer_preset = require('jest-puppeteer/jest-preset')
module.exports = merge.recursive(ts_preset, puppeteer_preset, {
globals: {
test_url: `http://${process.env.HOST || '127.0.0.1'}:${process.env.PORT || 3000}`,
},
})
If there are certain options that can't be 'merged' like that, just handle these cases manually.
Along these same lines, you can do this with the spread operator:
const tsPreset = require('ts-jest/jest-preset')
const puppeteerPreset = require('jest-puppeteer/jest-preset')
module.exports = {
...tsPreset,
...puppeteerPreset,
globals: {
test_url: `http://${process.env.HOST||'127.0.0.1'}:${process.env.PORT||3000}`,
},
}
For people that are looking for one preset plus typeScript
const { defaults: tsjPreset } = require('ts-jest/presets')
module.exports = merge.recursive(ts_preset, puppeteer_preset, {
preset: 'Your_Preset',
transform: tsjPreset.transform,
},
})
I've written my React app with ES6. Now I would like to write my tests also with ES6. So the challenge here is to configure karma.
Together with google I came this far with karma.config.js (I've omitted parts of the config file which are the same!):
...
files: [
'../node_modules/karma-babel-preprocessor/node_modules/babel-core/browser-polyfill.js',
'../app/**/*.jsx',
'../test/**/*.jsx'],
preprocessors: {
'app/**/*.jsx': ['react-jsx', 'babel'],
'test/**/*.jsx': ['react-jsx', 'babel']
},
'babelPreprocessor': {
options: {
sourceMap: 'inline'
},
filename: function(file) {
return file.originalPath.replace(/\.jsx$/, '.es5.js');
},
sourceFileName: function(file) {
return file.originalPath;
}
},
....
What I think this setup should do: 1) compile the JSX to JS and next babel should transform ES6 to ES5. This together with the polyfill I expected it should run in phantomjs for example. But no, here is the output from karma when I run it:
PhantomJS 1.9.8 (Mac OS X) ERROR
SyntaxError: Parse error
at Projects/ES6/app/js/app.jsx:35
PhantomJS 1.9.8 (Mac OS X): Executed 0 of 0 ERROR (0.027 secs / 0 secs)
[20:36:59] Karma has exited with 1
Line 35 of app.jsx contains the actual JSX part. So, for some reason the preprocessors seems to do not so much. Any help with the preprocessors would be appreciated ?
UPDATE: I have this almost working nog. Turns out that the preprocessors I had should be swapped like this
'../app/**/*.jsx': ['babel', 'react'],
'../test/**/*.jsx': ['babel', 'react']
Now, when I run this, I get:
Uncaught ReferenceError: require is not defined
I thought I had a polyfill for that :(
I use ES6 with Browserify and JSX. For compilation I use Babel. The following configuration works for me.
karma.conf.js
...
frameworks: ['browserify', 'jasmine'],
files: [
'Component.js', // replace with your component
'__tests__/Component-test.js'
],
preprocessors: {
'Component.js': 'browserify',
'./__tests__/Component-test.js': 'browserify'
},
browserify : {
transform : ['babelify']
},
...
__tests__/Component-test.js
var React = require('react/addons');
var TestUtils = React.addons.TestUtils;
var Component = require('../Component.js');
describe('Component', () => {
it('should work', () => {
var component = <Component />;
TestUtils.renderIntoDocument(component);
expect(component).toBeTruthy();
});
});
If you have any questions let me know.
#zemirico answer did not work for me and is slightly outdated.
Here is my own setup that you can use for karma.conf.js:
...
frameworks: ['jasmine', 'browserify'],
files: [
'src/*',
'tests/*'
],
preprocessors: {
'src/*': ['browserify'],
'tests/*': ['browserify']
},
browserify: {
debug: true,
transform: ['babelify']
}
...
It uses babelify instead of reactify, and has other dependencies. Thus, .babelrc in the project root is also needed:
{
presets: ['es2015', 'react']
}
The setup also requires the dependencies below to be included in package.json file:
"devDependencies": {
"babel-preset-react": "^6.5.0",
"babelify": "^7.2.0",
"browserify": "^13.0.0",
"jasmine-core": "^2.4.1",
"karma": "^0.13.22",
"karma-browserify": "^5.0.3",
"karma-chrome-launcher": "^0.2.3",
"karma-jasmine": "^0.3.8",
"watchify": "^3.7.0",
"babel-preset-es2015": "^6.6.0",
"react": "^15.0.1",
"react-addons-test-utils": "^15.0.1",
"react-dom": "^15.0.1"
}
Usage
Create a new React component in src/my-element.jsx:
import React from 'react';
export default class MyElement extends React.Component {
constructor(props) {
super(props);
this.state = {isActive: false};
this.onClick = this.onClick.bind(this);
}
onClick() {
this.setState({isActive: !this.state.isActive});
}
render() {
return (
<div onClick={this.onClick}>{this.state.isActive ? "I am active!" : "I am not active :("}</div>
);
}
}
Then, test it as such by creating spec in tests/my-element-spec.js:
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
import MyElement from '../src/my-element.jsx';
describe('MyElement', () => {
// Render a checkbox with label in the document
const element = TestUtils.renderIntoDocument(<MyElement />);
const elementNode = ReactDOM.findDOMNode(element);
it('verity correct default text', () => {
expect(elementNode.textContent).toEqual('I am not active :(');
});
it ('verify text has been changed successfuly after click', () => {
// Simulate a click and verify that it is now On
TestUtils.Simulate.click(elementNode);
// Verify text has been changed successfully
expect(elementNode.textContent).toEqual('I am active!');
});
});
Demo
Working example on GitHub.