1

I am new to Jest and Java Script in general. I wrote a test to one of my components but it seems to fail and I can't figure out how to fix it and what is wrong (Apparently something with enzyme).

It prints:

● Console

    console.log src/App.js:18
      props = {}
    console.log src/App.js:19
      url = ./api/user/undefined/

C:\Users\Itay\Documents\Matan - Microsoft\Matan\MatanClient\node_modules\react-dom\cjs\react-dom.development.js:62
    throw error;
    ^

Invariant Violation: The `document` global was defined when React was 
initialized, but is not defined anymore. This can happen in a test 
environment if a component schedules an update from an asynchronous 
callback, but the test has already finished running. To solve this, you can 
either unmount the component at the end of your test (and ensure that any 
asynchronous operations get canceled in `componentWillUnmount`), or you can 
change the test itself to be asynchronous.

The test I wrote was as simple as I could:

import React from 'react';
import PropTypes from 'prop-types';
import { shallow, configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { AdminViewComponent } from '../components/AdminViewComponent.js';

configure({ adapter: new Adapter() });

describe('<AdminViewComponent />', () => {
  it('renders an admin view', () => {
  const admin = shallow(<AdminViewComponent />);
  expect(admin.render()).toBeCalled;
  });
}); 

And the component itself looks like this:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {Typeahead} from 'react-bootstrap-typeahead'; // ES2015
import axios from 'axios';
import {WholeScreen} from './WholeScreenComponent.js';

export class AdminViewComponent extends Component{

  constructor(props) {
    super(props);

    this.state = {
      emailList: [],
      selectedUser: "",
      SelectedUserDonationData:{}
    };

    this._handleChange = this._handleChange.bind(this);
  }

 getInitialState(){
    return {
      // [{}] is weird, either use undefined (or [] but undefined is better).
      // If you use [], you loose the information of a "pending" request, as 
      // you won't be able to make a distinction between a pending request, 
      // and a response that returns an empty array
      emailList: undefined,
      selectedUser: undefined,
      SelectedUserDonationData:undefined
    } 
  }
  componentDidMount(){
    this.setState({emailList : undefined});
    return axios.get('./api/user/', {
        headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer '+ this.props.token
        }
        }).then(response => {
            const emailListResult = response.data;
            this.setState({ emailList : emailListResult });

        }).catch(function (error) {
              console.log(error);
        });
  }

  _handleChange(SelectedUser){
     this.setState({ selectedUser : SelectedUser, selectedUserDonationData: undefined });


    axios.get('./api/user/' + SelectedUser + '/' , 
       {headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer '+ this.props.token
        }
        }).then(response => {
            const selectedUserDonationDataResponse = response.data;
            this.setState({ selectedUserDonationData : selectedUserDonationDataResponse });
            console.log(selectedUserDonationDataResponse);

        }).catch(function (error) {
              console.log(error);
        });

  }

    render() {
      var adminView;
      if (!this.state.emailList){
        adminView = <div> Please wait while we retrive all users... </div>
      }
      else{
        adminView =<div> <div> Please select user to show his/her donations </div>        
                    <Typeahead 
                      placeholder="Select user email..."
                      onChange={this._handleChange}
                      options={this.state.emailList}/> </div>;
      }

      var selectedUserData;
      if (this.state.selectedUserDonationData){

        selectedUserData = <div className="AdminViewData"> 
                          <h4 className="DtatOf">Showing donations of : {this.state.selectedUser}</h4>
                              <WholeScreen  data={this.state.selectedUserDonationData.DonationsList}/>
                        </div>
      }

      var url = "./api/user/" ; 
      return(
      <div className="AdminView">

          {adminView}              
          {selectedUserData}

      </div>          
      );
    }
}

Thanks is advance!

4
  • Please update your code after adding adapter and let me know what error you get? Commented Sep 13, 2018 at 10:25
  • Where have you added Enzyme Adapter ? Commented Sep 13, 2018 at 10:32
  • 1
    Just added, and it passes, thank you ! Commented Sep 13, 2018 at 10:36
  • @SakhiMansoor Hi! Can you please try to assist me here? stackoverflow.com/questions/52984757/… Commented Oct 25, 2018 at 9:22

1 Answer 1

0

I believe your shallow renderer import should look like this:

import { shallow, configure  } from 'enzyme';

EDIT: could you add the following import and initialization below your shallow renderer.

import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });

As stated in the Enzyme docs as well: enzyme installation

Sign up to request clarification or add additional context in comments.

8 Comments

At the beginning it was as you said but still did not work, though I will edit my question with your fix
@I.zvi please check my revised answer. The error seems to state that some additional configuration is needed. npm install enzyme-adapter-react-16 as well if you haven't already.
Can you provide a brief explanation about configure({ adapter: new Adapter() }); As I am totally new into it I have never heard about it. What is the "Adapter" and "Configure" ?
Also, I followed what you said, however there seems like still there is an issue, I edited my question so you can see now
You need to configure the correct adapter that you intent to use and test with enzyme. In your case I'm assuming this is the React 16 adapter. I've added a documentation link as well to the enzyme docs where this is explained. If you look at the error text you can see that it says the same thing there as well. It just means that you need the correct Adapter configured before you run any tests and that is what the lines I've suggested above should achieve.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.