testing fails with Jest

All we need is an easy explanation of the problem, so here it is.

I have got a code for which I have to perform tests on. After installing Jest and using it with enzyme for testing different components, now I have to check that only Authorized tenants can access my website. Both client side and server side are built on Azure.

All I want to do is to test that a known tenant (See App.js) will be authorized.

For this tenants testing, I should use the App.js.

I cannot figure out for what reason my test fails ?

App.test.js :

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { shallow, configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

it('renders without crashing', () => {
    const div = document.createElement('div');
    ReactDOM.render(<App />, div);
});

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

const tid = "72f988bf-86f1-41af-91ab-2d7cd011db47";
it('Authorizes a known tenant', () => {
const app = shallow(<App tid={tid} />);
const el = app.find('[src=microsoft-gray.png]');
expect(el.exists()).to.equal(true);

});

The error:

  ● Authorizes a known tenant


TypeError: Cannot read property 'equal' of undefined

  16 |     const app = shallow(<App tid={tid} />);
  17 |     const el = app.find('[src="microsoft-gray.png"]');
> 18 |     expect(el.exists()).to.equal(true);
     |     ^
  19 | });

App.js :

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import './App.css';
import { Grid, Row, Col, Table, Panel, Image, Tabs, Tab, Nav, NavItem, Alert } from 'react-bootstrap';
import _ from 'lodash';
import $ from 'jquery';
import Request from 'react-http-request';
import { AdminViewComponent } from './components/AdminViewComponent.js';
import { WholeScreen } from './components/WholeScreenComponent.js';
import logo from './logo.svg';

class App extends Component {
    render() {
        var url = "./api/user/" + this.props.userName + "/";
        console.log("props = " + JSON.stringify(this.props));
        console.log("url = " + url);
        var userCompanyIcon;
        //if (this.props.tid == "49d3d3cf-cde6-4161-8d6d-1789042d7b01"){
        if (this.props.tid == "72f988bf-86f1-41af-91ab-2d7cd011db47" || this.props.tid == "49d3d3cf-cde6-4161-8d6d-1789042d7b01") {
            userCompanyIcon = <Image className="userCompanyIcon" src="microsoft-gray.png" responsive />;
        }

        return (
            <div className="App">
                <div className="App-header">
                    <Grid>
                        <Row>
                            <Col xs={6} sm={6} md={6}>

                            </Col>
                            <Col xs={2} sm={2} md={2}>

                            </Col>
                            <Col xs={4} sm={4} md={4}>

                                <div className="Hello">Hello, {this.props.fisrtName} </div>
                            </Col>

                        </Row>
                        <Row>
                            <Col xs={4} sm={4} md={4}  >
                                {userCompanyIcon}
                            </Col>
                            <Col xs={4} sm={4} md={4}  >

                            </Col>
                            <Col xs={4} sm={4} md={4}>
                                <Image className="companyIcon" src="MatanTransperent.png" responsive />
                            </Col>
                        </Row>
                    </Grid>
                </div>


                <div className="App-content">

                    <Request
                        url={url}
                        method='get'
                        accept='application/json'
                        headers={{ 'Authorization': 'Bearer ' + this.props.token }}
                        verbose={true}>
                        {
                            ({ error, result, loading }) => {
                                if (loading) {
                                    return <div>Loading...</div>;
                                } else {
                                    if (result == null || result.statusType == 4 || result.statusType == 5) {
                                        return <div> An unknown error has occured. Please try again.  </div>;
                                    }
                                    else {
                                        var returnObject = JSON.parse(result.text);
                                        if (returnObject.isAdmin == false) {
                                            return <WholeScreen data={returnObject.DonationsList} />;
                                        }
                                        else if (returnObject.isAdmin == true) {
                                            return <AdminViewComponent token={this.props.token} />;

                                        }
                                    }
                                }
                            }
                        }
                    </Request>
                </div>
            </div>
        );
    }
}

export default App;

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

You are searching on ID #tid, and it seems like you don’t have any elements that have an ID of #tid. You are passing tid as an property and aren’t using it afterwards, aside from you conditionally rendering logic.

You also have other options than using CSS selectors to find your element (see here). If your goal is actually to see if the image renders you could try app.find(‘.userCompanyIcon’);or app.find('[src="microsoft-gray.png"]');

If you were actually checking whether your property is set then app.prop('tid') would also give you the tenant id.

So either:

const tid = "72f988bf-86f1-41af-91ab-2d7cd011db47";
it('Authorizes a known tenant', () => {
    const app = shallow(<App tid={tid} />);
    const el = app.find('.userCompanyIcon');
    expect(el.exists()).toEqual(true);

});

Or:

const tid = "72f988bf-86f1-41af-91ab-2d7cd011db47";
it('Authorizes a known tenant', () => {
    const app = shallow(<App tid={tid} />);
    const el = app.find('[src="microsoft-gray.png"]');
    expect(el.exists()).toEqual(true);

});

Or the below, but this doesn’t test much:

const tid = "72f988bf-86f1-41af-91ab-2d7cd011db47";
it('Authorizes a known tenant', () => {
    const app = shallow(<App tid={tid} />);
    const tid = app.prop('tid');
    expect(tid).toEqual('72f988bf-86f1-41af-91ab-2d7cd011db47');

});

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply