Skip to content

Commit

Permalink
Testing Functional Components Continued
Browse files Browse the repository at this point in the history
  • Loading branch information
Ch-sriram committed Sep 15, 2020
1 parent ffe195a commit b70e184
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 116 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,4 @@ Installing Dependencies:
*Note*: If [cra](https://create-react-app.dev/docs/getting-started) is used to create the react app, `jest` will be pre-installed.

1. Testing Functional Components using `describe()`, `it() / test()` & `expect()`: [Commit Details](https://github.com/Ch-sriram/burger-builder/commit/b2245df8efa3f35105390de479bd094ca7e5b722)
2. Testing Functional Components Continued: [Commit Details]()
Original file line number Diff line number Diff line change
@@ -1,136 +1,86 @@
// NOTE: Read the comments as numbered from 1 onwards.

/** 1 */
// Naming this file as: "NavigationItems.component.test.jsx" is
// important because that's automatically picked up by CRA once
// we run the `npm test` command and so, this `.test.jsx` files
// will also be included when running the tests.


/** 2 */
/**
* A `.test.jsx` file uses Jest by default and Jest gives us a
* couple of methods to define the test(s).
*
* Some of the important methods provided by Jest are:
* 1. describe(description: string, callback: fn)
* 2. test(description: string, callback: fn, timeout: int)
* 3. it() -- alias for the test() method.
*/


/** 5 */
import React from 'react';
import NavigationItems from './NavigationItems.component';

/** 6 */
import NavigationItem from './NavigationItem/NavigationItem.component';

/** 4 */
// To connect the React application to enzyme testing utility
// package, we use the configure method to pass in an 'adapter'
// which is basically the connection between enzyme and react.
// IMPORTS FOR ENZYME & REACT CONFIGURATION
import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

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

/**
* for a single component, we can test more than one aspect
* of that component. For example, we previously tested for
* <NavigationItems /> component if it definitely has exactly
* 2 <NavigationItem /> components or not, when the user is not
* authenticated.
*
* Now we can also test when the user is authenticated, are
* there exactly 3 <NavigationItem /> components present or
* not, which is another valid test, as shown below after/in
* line #36 below.
*/

/** 3 */
// https://jestjs.io/docs/en/api#describename-fn
describe('<NavigationItems />', () => {
// https://jestjs.io/docs/en/api#testname-fn-timeout
// NOTE: it() and test() are both same functions where it()
// is the alias of the test() method.
test('should render two <NavigationItem /> elements if not authenticated', () => {
// Here, we write our TEST LOGIC, and for that - we create
// an instance of the <NavigationItems /> component as how
// it is rendered to the real DOM through React and then
// have a look into the rendered component and see what was
// rendered for the case that the respective prop (which
// is `isAuthenticated` prop) is true/false.

// Now we might think that we might have to render the
// entire React application because <NavigationItems />
// is just one tiny component in the entire application,
// and that's where enzyme comes in. Enzyme allows us to
// render these individual components, in a standalone
// manner, independent of the entire React application.
// describe('<NavigationItems />', () => {
// // https://jestjs.io/docs/en/api#testname-fn-timeout
// test('should render two <NavigationItem /> elements if not authenticated', () => {
// // https://enzymejs.github.io/enzyme/docs/api/shallow.html
// const wrapper = shallow(<NavigationItems />);

// That's the whole idea behind the enzyme package, we can
// write Unit Tests (Isolated Tests) - tests where we don't
// need to render the complete React application.
// // To know more, look into the following links:
// // 1. API: https://jestjs.io/docs/en/expect#expectvalue
// // 2. Usage: https://enzymejs.github.io/enzyme/docs/api/shallow.html
// expect(wrapper.find(NavigationItem)).toHaveLength(2);
// });

// for that, we need to connect the React app to the enzyme
// package. Configuration can be read in #4.
// test('should render three <NavigationItem /> elements if authenticated', () => {
// const wrapper = shallow(<NavigationItems isAuth />);
// expect(wrapper.find(NavigationItem)).toHaveLength(3);
// });
// });

// Now we can render a mock <NavigationItems /> component
// using the shallow() method from 'enzyme' testing
// utility package. shallow() method is the best option to
// render a React component in many circumstances. Enzyme
// also offers 2 other alternatives, which we'll look into
// later in the enzyme docs.
/**
* Now instead of defining the `wrapper` const which has the
* same component which is being tested, we can use the method
* beforeEach() provided by Jest (other method is afterEach(),
* which is used for clean-up work) and we can do some general
* setup (initialization of variables/components that are in
* common use), which is demonstrated below:
*/

describe("<NavigationItems />", () => {
let wrapper;

// https://jestjs.io/docs/en/api#beforeeachfn-timeout
beforeEach(() => {
// https://enzymejs.github.io/enzyme/docs/api/shallow.html
// Using shallow(), we'll mock render the
// <NavigationItems /> component and test the respective
// component.

// To the shallow() method, we pass in <NavigationItems />
// component and so, we essentially pass in JSX, and to
// make use of JSX in our code, we need to import React
// from 'react' as seen in #5.
const wrapper = shallow(<NavigationItems />);

// Now we can have a look into the `wrapper` const in the
// test, where we now write our expectation using the
// expect() method which is provided by Jest.

// To know more, look into the following links:
// 1. API: https://jestjs.io/docs/en/expect#expectvalue
// 2. Usage: https://enzymejs.github.io/enzyme/docs/api/shallow.html

// expect() method inside a test simply asserts what is to
// be expected of this component. For example, our
// component, which is the <NavigationItems /> component,
// inside the `wrapper`, we want 2 <NavigationItem />
// components, and so for that, we'll use the find() method
// provided by 'enzyme' to for the `wrapper` object, which
// is passed to the expect() method.

// expect(wrapper.find(NavigationItem)); // this is simply saying we expect to find a NavigationItem component, but it doesn't exactly specify that we want to find 2 of them exactly, and for that, we can chain the utility methods made available by Jest, as follows:
wrapper = shallow(<NavigationItems />);
});

// https://jestjs.io/docs/en/api#testname-fn-timeout
test("should render two <NavigationItem /> elements if not authenticated", () => {
expect(wrapper.find(NavigationItem)).toHaveLength(2);
});

/**
* NOTE that the `wrapper` is sent a shallow rendered copy
* of the <NavigationItems /> component where the `isAuth`
* prop is not sent, and that means, it will be taken as
* false by default.
*/
test("should render three <NavigationItem /> elements if authenticated", () => {
// Here, we'll have a failed test because there will only
// be three (3) <NavigationItem /> components in the
// <NavigationItems /> when the `isAuth` prop of the
// <NavigationItems /> component is true.

// And so, to set the `isAuth` prop to the common wrapper
// (that we're using for both the tests) for this
// respective test, and for that, we can do 2 things:
// 1. We can simply assign the <NavigationItems /> with
// the `isAuth` prop to the `wrapper` variable defined
// above i.e.,
// wrapper = shallow(<NavigationItems isAuth/>);
// But that's not the standard way, another method is:
// 2. We can access the common `wrapper` variable and on
// that, before calling the expect() method, we can use
// the setProps() method as follows:
// https://enzymejs.github.io/enzyme/docs/api/ShallowWrapper/setProps.html
wrapper.setProps({ isAuth: true, });
expect(wrapper.find(NavigationItem)).toHaveLength(3);
});
});

/**
* We can run tests using `npm test`, if the react app's config
* is setup through CRA.
*/

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The code without the comments:

// import React from 'react';
// import NavigationItems from './NavigationItems.component';
// import NavigationItem from "./NavigationItem/NavigationItem.component";

// // Configuration of enzyme and react.
// import { configure } from 'enzyme';
// import Adapter from 'enzyme-adapter-react-16';
// configure({ adapter: new Adapter(), });

// describe('<NavigationItems />', () => {
// test('should render two <NavigationItem /> elements if not authenticated', () => {
// const wrapper = shallow(<NavigationItems />);
// expect(wrapper.find(NavigationItem)).toHaveLength(2);
// });
// });

0 comments on commit b70e184

Please sign in to comment.