Mocks: Testing Reactjs Components

Have recently been learning how to test Reactjs components via unit testing using jest and @testing-library/react which come prebundled with any new Reactjs app created with CRA (Create-react-app CLI).

Mocking functions with jest

Many times components have eventHandlers (onclick, onchange, onblur etc) passed down to them via props and with tests these event handlers are usually mocked out.

Mocking ajax/fetch/axios calls in tests.

Since almost every app has a remote request that they make, learning to mock async calls seemed very important. For this, a package called MSW ( model service worker) can be used to intercept ajax calls to external remote sources to keep them local so that tests are less flaky and quicker.

My package.json for the example that I’m running:

Notice the inclusion of jest-enviroment-jsdom-sixteen. Further more, it’s use here:

I added this to suppress some errors about not using act() during async calls. It can be further explained here: https://kentcdodds.com/blog/fix-the-not-wrapped-in-act-warning

To use MSW we have to setup a server with endpoints that it will intercept. Might want to break your endpoints in to a separate file but for this example I kept them all in the same server.js under the mock directory.

What above will do is intercept any call to “https://jsonplaceholder.typicode.com/todos/1”  and instead return a json object of

Also, we want our server to setup and tear down for each and every test and for that we create a setupTests.js within the /src folder:

The testing library should automatically see this setupTests.js file and run it during testing.

So the actual component we are going to test is called Todo.js

The ajax call is actually within the useEffect that gets called once on the initial rendering of the component.

Here is our testing file for Todo component. Todo.test.js

The actual test we are interested in is “msw intercepts the axios on effect” as this is the one that will check if the ajax call was intercept and replaced with our mocked return  data that we get from MSW.

First we render the component which will trigger the intitial useEffect call which then triggers the ajax call to ultimately update our title state.

The line below enables us to “wait”(async) for the ajax call to complete and for the state to be updated before we check to see if the mocked data was in fact returned via MSW.

Our tests pass as MSW does infact return the mocked title of “the mocked title” which is what our test is looking for.

Mocking 3rd party libraries or modules

We can use jest to mock a library so our tests are easier to write without going in to the complexity of incorporating the libraries that maybe used. For example:

We mocked the useGetLocation function that is from the ‘react-get-location’ library and made it so we return a custom state hook to be used in our tests instead of the normal non-mocked version of useGetLocation

(video lesson 184 )

 

 

Notes for webpack configs to output single files for js and css bundles and more

I often use a site to build webpack configs https://createapp.dev/ and I normally like to have my js and css compiled to one file each within /dist

Out of the box, it handles the entry/output for the .js but a little bit needs to be added to do the same for the .css

Here is an example webpack.config.js

Some important parts added to have the css compile to a single file. First is that the scss file(s) need to be added as an entry:

Secondly, the MiniCssExtractPlugin needs to have an object with the destination css file name added to it as you see here:

 

To process es6+ features like async/await

We must add the below dependency:

Finally, alter the .babelrc to look like :

 

Reactjs using recoil.js for state management notes

Recoil.js is being designed by facebook apparently to replace redux so I figured I’d take a look.

My sample Codesandbox

Atoms  – most basic for of state that can be shared amongst components and or selectors. It requires a “key” which must be unique and to initialize with a value(s) use default.

 

useRecoilState – Used to read and write an atom from a component.

Selectors – a pure function that will basically just return a computed value based on atom(s) and/or other selectors. By default, selectors are not writable and so can not alter the atoms/selections within it; only use it to provide its produced computed value. (get)

useRecoilValue – used to get/use the computed value from a selector.

Creating “n” amount of atoms

Sometimes we need an unknown amount of state atoms in an app. One way is to create a function that will returned a memorized atom based on an ID. We memorize it that way if it is the same ID we use the already made atom and return that instead of regenerating the atom.

For example:

Then we can use it in components like below:

 

Various onFocus animations using Fluent Forms

*Note – I’ve noticed the dark theme on this website can make the onFocus effects harder to see. If that is the case, try viewing this blog post with the “light” theme.

Fluent Forms onFocus Examples

To be used with Text or TextArea type inputs in Fluent Form. Every example needsto add the class “animated_form_element” under the Advanced Options for each of the text/textarea’  “Element Class” field such as below:

For each set of animations, hit the reveal button to show the code that has to be added to your Fluent Form’s Custom CSS/JS sections. That section can be found under “Settings & Integrations tab -> Custom CSS/JS”

Underline

Drop In Underline Example:

dropin_underline

Left To Right

Adding on focus animations to a Fluent Form

Fluent Forms is a popular WordPress plugin that allows you to make forms easily. One thing I didn’t like is that there is no onFocus options for animations etc. With inspiration from a different post about hyper link hover animations ( found here ) for Divi menu modules, I added on focus animation for my Fluent Form. I created this small tutorial to show how I did it.

Here is an example of what the outcome looks like:

Fluent Forms animated on focus

To do this, you first have to add the class “animated_form_element” under the Advanced Options for each of the text/textarea’  “Element Class” field such as below:

 

Next, we need to add some custom css and javascript to our form. We add it by going to the form’s  “Settings & Integrations tab -> Custom CSS/JS” section.

For the CSS, it really depends on the look you are going for but for this example I wanted a bottom border to be shown on the input/textarea field regardless if it has focus or not. I also removed the default border radius on the input field as well. Here is the customer css to accomplish those things.

I use !important to be sure it overrides Fluent Forms default styles.

Next, let’s add the styles needed for the actual animation itself as well as modifying how the “This field is required.” is shown:

The error message for “This field is required” aka .text-danger is made switched to absolute  positioning and in this case has been set 5px from the bottom of the input fields container. Really, this could be different based on how you want the field to show on the form. You could use top instead for example. However, the .text-danger must be made absolute as we need it out of the document flow so it won’t create visual bugs with extra space in between the inputs border bottom  and the border bottom that is used to create the animation.

Finally, we need to add some custom javascript to the form as well:

 

And that’s it for this example really.

You may notice I named the actual animation class name “animatedStyleName” which is generic. I did this because really you could take many of the different animations listed in the divi-menu-effects.css you can download from this site and replace the rules of animatedStyleName to do different types of animations. You have to subscribe to his newsletter in order to get the previously mentioned .css file that has the different animations. Some of the animation examples on that site require more work than what I described but I plan on writing an extension of this tutorial if it seems people might want it.

Can download the Fluent Form export example here . You may have to right click -> “save link as” for it to work.

Live example:

contactus