Category

React Native

Using Jest for Unit Testing of Gatsby, Typescript and React Testing Library

The task to set up Jest and React Testing library for TDD using Gatsby is an easy one.Its tricky as i planned to use Typescripts in my test.

Firstly , i installed jestbabel-jest and babel-preset-gatsby ensuring the presence of babel preset(s) which can be used internally for Gatsby site.

npm install –save-dev jest babel-jest babel-preset-gatsby identity-obj-proxy tslint-react @types/jest

Configure Jest for checking its working with Gatsby

As Gatsby has its own babel configuration so we have to manually tell jest to use babel-jest. the gatsby website tells to create  jest.config.js file. look at the code below

jest.config.js

const path = require(“path”)

module.exports = {
setupFilesAfterEnv: [
path.resolve(dirname, “./jest-configs/setup-test-env.js”) ], transform: { // “^.+\.(tsx?|jsx?)$”: “ts-jest”, “\.svg”: “/jest-configs/__mocks/svgTransform.js” ,
“^.+\.(tsx?|jsx?)$”: <rootDir>/jest-configs/jest-preprocess.js,
},
moduleNameMapper: {
// “\.svg”: ./jest-configs/__mocks__/file-mocks.js,
“\.svg”: <rootDir>/jest-configs/__mocks__/svgTransform.js,
“typeface-“: “identity-obj-proxy”, “.+\.(css|styl|less|sass|scss)$”: identity-obj-proxy, “.+\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$”: <rootDir>/jest-configs/__mocks__/file-mocks.js, }, testPathIgnorePatterns: [node_modules, .cache, public], transformIgnorePatterns: [node_modules/(?!(gatsby)/), \\.svg], globals: { PATH_PREFIX: “, }, testRegex: “(/tests/.|\.(test|spec))\.(ts|tsx)$”,
moduleFileExtensions: [
“ts”,
“tsx”,
“js”
],
collectCoverage: false,
coverageReporters: [
“lcov”,
“text”,
“html”
]
}

svgTransform.js

module.exports = {
process() {
return ‘module.exports = {};’;
},
getCacheKey() {
// The output is always the same.
return ‘svgTransform’;
},
};

The function of transform option is to tell Jest that all ts, tsx, js or jsx files should be transformed using a jest-preprocess.js file.

jest-configs/jest-preprocess.js

const babelOptions = {
presets: [
‘@babel/preset-react’,
‘babel-preset-gatsby’,
“@babel/preset-typescript”
],
};

module.exports = require(“babel jest”).createTransformer(babelOptions)

some code should also be put in setup-test-env.js .
The Jest Configuration docs explains the setupFilesAfterEnv: .... configuration option.

A list of direction or path to modules which run some code to configure or set up the testing framework before each test.

jest-configs/setup-test-env.js

import “@testing-library/jest-dom/extend-expect”

That should have Jest properly configured. Now, I’ll install the testing library and jest-dom as dev-dependencies with npm.

npm install –save-dev @testing-library/react @testing-library/jest-dom

Now run npx jestand now our code is good to go

SO NOW WE ARE GOOD TO GO

Now i will write my first test and run it. I like TDD because it is fast. We can write test before writing code. A test should fail at the beginning Read this up.
Now i will create a folder named __tests__ in my root folder of project. Then i will create a file named  test.spec.tsx and paste this code in it.

tests/test.spec.tsx

import React from "react"
import { render } from "@testing-library/react"

// You have to write data-testid
const Title = () => <h1 data-testid="hero-title">Gatsby is awesome!</h1>

test("Displays the correct title", () => {
  const { getByTestId } = render(<Title />)
  // Assertion
  expect(getByTestId("hero-title")).toHaveTextContent("Gatsby is awesome!")
  // --> Test will pass
})

Run commands like Yarn or npm install if you get errors like.

Cannot find module 'react' from 'test.spec.tsx'
    > 1 | import React from "react"

YAAYYY WE ACCOMPLISHED UNIT TESTING WITH TYPESCRIPT AND GATSBY AND JEST AND REACT TESTING LIBRARY

I am very happy with this . I will just start out Typescript with React so this was a great deal of learning for me. I’ll put up more post about writing real code using TDD. stay tuned

Mobile Applications architecture -React Native VS Native

Having an iOS and android background i struggled working with react native. i had no experience of working in this environment before and i worked with mobile development previously. i shifted to this new environment to develop the mindset of tech skills as a web developer. i was still understanding the mobile ecosystems rules like low memory usage and having battery of users, UI and others.

After passing the boundary of JavaScript learning norms, the new pattern of React, and what React Native includes , i next made a move to understand the structuring of app. My aim was to understand the path that is needed to be followed in order to structure the apps. My goal was to have knowledge for native development, and compare the tech worlds.

Native World

Nowadays, for many people with native background , its not difficult for them to decide the architecture of their app. these people have set some good options like MVP, MVVM and VIPER (mostly iOS). These people have the following goals in their mind:

  • unrelating the supply from business logics
  • developing testable applications
  • structuring of the app in modules for defining responsibilities

There was no right way decided by google or apple for many years, but 2 years ago google described their take at Google I/O and published a detailed blog ( detailed blog post) about structuring of app according to them and added extensive frameworks to android to support them .

The logic behind this step was to separate screens into their native components, with UI, business logics, networks and storage, all in their own entities. Look at the following diagram:

React Native

Most decisions related to architecture comes from FED world as ract native is based on react. It can be difficult for the react native developers initially as the ecosystem is different and decomposed between the different solutions.

After viewing the architecture we come to know that the web is mostly aligned with Flux. The main goal behind this was to develop one directional and predictable flow of data for your app, so it gets easy to understand and debug.

Redux is the best known implementation of flux despite many other implementations .

the application state is kept in Playstore or other stores and any change in store changes the parts of app. Look at the picture below:

Image for post

the components separate the actions, actions in return do something and update the store which changes the components in a good way. In above diagram differences and similarities can be seen.

let us view the differences and understand their existence and process parallel to them. I use android most of the time but in iOS the fragments can be switched to view controller and have feels like home.

Smart Components = Fragments

As in react native we speak about screens and in react we speak in terms of components. These components are the building units of all screens. A screen has many components and most of them are dumb , some are smart and are connected with the store or query needed by the data.

Some screens have smart components and access their own store with their business logics. for :

Image for post

This example describes the addition of task screen in the to do list of the application. It contains many smart components like pick location which has its own state or store, user interface states and business logic storage and server API. This helps to develop each part even when there are different teams and have screen which is a dumb container.

Native equivalent:

The notion of composing your screen into different separate components is also present. Each smart component can be its own part in native. The screen is result of combination of several small components , each of them having its own logic and interactive environment. The logics or the states are taken out of different components, which takes us to the next step.

Actions + Store = ViewModel

This part of component is in charge of all the states of the components and logics related to business and presentation. Its the most important part as it helps in the implementation process. This is the main heart of the application.

By using Redux , we can dispatch the actions and have to wait till any change in store and we check the changes if they are appropriate or not. In each action we can request any network, ask queries related to storage and upgrade the stores. The object named store is global and not attached to any other component life-cycle.

Native Counterpart:

Actions are similar to calling methods in appropriate view models. Store state is in the view model . Any change in the state disturbs the UI and gives benefits of reactivity.

Frameworks like RXjava and RXswift makes reactivity very simple.

Some differences noted are listed below:

The state is private in ViewModel in native, while in Redux the store is global. It has an advantage that when one component can effect another component the UI remains consistent.

Some disadvantages include the leakage of state to other components due to which it can be misused and rely on inside details that should be kept hidden . Also when one component is to be shown on the screen more than once , so updating that store can have issues and screens effect each other causing difficulty in debugging errors . To remove such issues we should decide what must be kept in the store an what not.

Remote Server

No difference.

Async Storage ≠ Relational DB

Now here lies big differences.

In react we have to use key/value storage , in native we use relational DB solutions. Both approaches have their own advantages and disadvantages so people with DB background find it difficult to work with key/value storages and its hard for them in schema portion.

Summary

We can see that initially it seems like recat native was different from native development, but after viewing we came to know that many ideas are similar with small chnages.

While comparing the architectural patterns its seen that in the android trends and is called MVI which aims to bring the flux pattern to native development.

Also Redux is the most used library and most used state management , although there are others like Mobx which brings MVC back to the web.

For mobile developers with native knowledge should take start from react native path, as both have similar goals mainly SOLID principles of software engineering.

Implementation might have some differences ; some are more functional or reactive, some with boilerplate, but mainly they have same goals.