image: jest

Jest: make your code more secure and reliable

jest

testing-component

jest.mock

tests-library-react

unitary tests

coverage

DOM-events-testing

If you develop in React, you've probably heard of Jest - one of the most popular tools for testing JavaScript. Jest is easy to use and offers a wide range of features for testing components, functions and libraries. In the content of these posts, you will be shown how to install and configure Jest and react-testing-library, and how to write tests for your projects. Introduction to Jest - What is Jest and why use it? Jest is designed to be easy to use and offers powerful features for testing JavaScript projects, including support for asynchronous tests and integration tests. It is very popular among React developers as it has easy integration and offers a variety of features for testing React components. Jest is also fast, which means you can run your tests faster than with other testing frameworks. Jest runs tests in parallel, which can save time on larger projects. In addition, Jest has an intuitive syntax that makes creating tests simpler and easier to understand. Installing Jest and the React Test Library Before you can start using Jest, you'll need to install it in your project. Fortunately, installing Jest is simple and quick. First, you'll need to install Node.js on your computer if you haven't already. After installing Node.js, you can install Jest using npm. Just open the terminal and type the following command: npm install --save-dev jest @testing-library/react @testing-library/jest-dom Configuring Jest in your project Agora que o Jest está instalado em seu projeto, você precisa configurá-lo. Você pode configurar o Jest adicionando um arquivo de configuração na raiz do seu projeto chamado jest.config.js. Este arquivo permite que você configure várias opções para o Jest, como o diretório de arquivos de teste, o padrão de nomenclatura para arquivos de teste e outras opções. Here is a basic example of a configuration file: module.exports = { testMatch: ["**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)"], testPathIgnorePatterns: ["/node_modules/"], }; This configuration file tells Jest to look for test files in the tests directory and in any files that end in .spec.js or .test.js. It also tells Jest to ignore the node_modules directory. Basics of Testing with Jest Create a file called sum.test.js in the tests directory. Add the following code to the file: function sum(a: number, b: number) { return a + b; } test("adds 1 + 2 to equal 3", () => { expect(sum(1, 2)).toBe(3); }); This test verifies that the sum function correctly adds two numbers. The test is run using Jest's test function. The test function takes two arguments - a description of the test and a function containing the test logic. The test function uses Jest's expect function to check whether the output of the sum function equals 3. To run the test, open a terminal and run the following command: npm run test This command starts Jest and runs all the tests in your project. You'll see output from Jest in the terminal, which will show you whether the test passed or failed. Testing React components with Jest and @testing-library/react Jest is widely used for testing React applications. To test React components with Jest, you can use the @testing-library/react test library. This library provides functions to simulate user events, access DOM elements and check component state. Here is an example of testing a React component using @testing-library/react: import { Button } from "@components/button"; import { render } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; describe("Button", () => { it("renders a button", () => { const { getByText } = render(<Button label="Click Me" />); const button = getByText("Click Me"); expect(button).toBeInTheDocument(); }); it("calls onClick when button is clicked", () => { const onClick = jest.fn(); const { getByText } = render(<Button label="Click Me" onClick={onClick} />); const button = getByText("Click Me"); userEvent.click(button); expect(onClick).toHaveBeenCalled(); }); }); This test verifies that a Button component renders correctly and that the onClick function is called when the button is clicked. The test uses the @testing-library/react render function to render the Button component. It uses the getByText function to get the button's DOM element and the userEvent function to simulate a button click. It uses the jest.fn function to create a mock function for onClick and the toHaveBeenCalled function to check if the mock function was called. Jest component simulation Sometimes you may need to isolate a component during a test and mock one or more of its children. Jest provides an easy way to do this using the jest.mock function Here is a test example that simulates a child component in a parent component: import Parent from "@components/button"; import { render } from "@testing-library/react"; jest.mock("./Child", () => <div>Mock Child Component</div>); test("renders the parent component with a mocked child", () => { const { getByText } = render(<Parent />); const child = getByText("Mock Child Component"); expect(child).toBeInTheDocument(); }); This test simulates a Child component on a Parent component. It uses the jest.mock function to replace the Child component with a mock component. The test uses the render function to render the Parent component and the getByText function to get the mock child component's DOM element. Testing React button components step by step Button components are common in React apps and can be easily tested with Jest. Here's a step-by-step guide to testing button components with Jest: Create a file called Button.test.js in the tests directory. Import the Button component and the @testing-library/react test library. Write a test that verifies that the Button component renders correctly. Write a test that checks if the onClick function is called when the button is clicked Write a test that checks whether the button is disabled when the disabled property is set to true. Here is a code example for testing a button component: import Button from "./Button"; import { render } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; describe("Button", () => { it("should be renders a button", () => { const { getByText } = render(<Button label="Click me" />); const button = getByText("Click me"); expect(button).toBeInTheDocument(); }); it("should be calls onClick when button is clicked", () => { const onClick = jest.fn(); const { getByText } = render(<Button label="Click me" onClick={onClick} />); const button = getByText("Click me"); userEvent.click(button); expect(onClick).toHaveBeenCalled(); }); it("should be disables the button when disabled is true", () => { const { getByText } = render(<Button label="Click me" disabled />); const button = getByText("Click me"); expect(button).toBeDisabled(); }); }); This code tests that the Button component renders correctly, that the onClick function is called when the button is clicked, and that the button is disabled when the disabled property is set to true. Jest Test Coverage Jest provides a code coverage tool that helps you verify that your tests are covering all of your code. Code coverage is a measure of the percentage of code that is executed while running tests. The higher the code coverage, the more likely you are to find bugs in your code. To use Jest's code coverage tool, run the following command in the terminal: npm run test -- --coverage This command starts Jest and runs all the tests in your project and generates a code coverage report. You can open the coverage/lcov-report/index.html file in your browser to see the code coverage report Advanced Jest Techniques Jest provides many advanced features for testing such as parallel testing, real-time testing, and integration testing. Here are some tips for using these advanced features: Use Jest's --watch option to run tests in real time while you make code changes. Use Jest's --coverageThreshold option to set minimum code coverage thresholds. Use Jest's --maxWorkers option to run tests in parallel across multiple processes. Use the supertest test library to test Node.js APIs. Conclusion Jest is an easy-to-use and widely used JavaScript testing framework for testing React applications. In this article, we've seen how to install and configure Jest and the React test library, how to write basic and advanced tests with Jest, and how to use advanced features like parallel testing and code coverage. I hope this article helps you become a Jest master and write quality tests for your JavaScript applications. If you want to learn more about Jest and the React test library, visit Jest's official documentation and its's from @testing-library/react

Gabriel Dürr M.

-

image: reactjs banner

ReactJS 18 guide for beginners

Reactjs

Web development

Front-end

SPA (Single Page Applications)

React JS is a popular JavaScript library that allows you to create interactive and dynamic user interfaces. It is used by thousands of developers worldwide to build scalable and efficient web applications. If you are new to React JS 18, this guide is for you. Introduction to ReactJS React JS is a JavaScript library for building user interfaces. It was developed by Facebook and maintained by an active community of developers. React JS is based on components, which are reusable building blocks that can be used to build user interfaces. React JS is one of the most popular JavaScript libraries and is used by companies like Netflix, Airbnb, Instagram, Uber and many others. It is known for its efficiency and scalability, which makes it a popular choice for large-scale web applications. Environment Setting Before you start working with React JS, you need to set up the development environment. This involves installing Node.js and the React CLI. Node.js is a platform for running JavaScript outside the browser, while React CLI is a command-line tool for creating and managing React projects. Creating a React project NOTE: You need to install Node.js, go to the official website and download the latest version. To create a new React project, type the following command in the terminal: npm create vite@latest NAME OF APP --template react Components in React JS Components are the foundation of building interfaces in React JS. They are like little building blocks that can be combined to create more complex interfaces. Each component has its own state and properties, which can be updated to reflect changes in the interface. To create a component in React JS, you can use a function with the functional paradigm. The function receives the properties as arguments and returns what will be rendered in the interface. type myComponentProps = { title: string; description: string; }; export const MyComponent = ({ title, description }: myComponentProps) => { return ( <div> <h1>{title}</h1> <p>{description}</p> </div> ); }; State in ReactJs State management is an important part of app development in React JS. The state is an object that represents the current state of the interface. It can be updated to reflect changes to the interface. React JS has a unique approach to state management. Instead of modifying the state directly, you should use the useState() method. useState() is used to update the state and notify React JS to re-render the interface. import { useState } from "react"; type myComponentProps = { title: string; description: string; }; export const MyComponent = ({ title, description }: myComponentProps) => { const [count, setCount] = useState(0); function handleClick() { setCount(prevState => prevState + 1); } return ( <div> <h1>{title}</h1> <p>{description}</p> <button onClick={handleClick}>Click Here</button> </div> ); }; State management with Context API State management is a fundamental aspect of ReactJS application development. The ContextAPI is a powerful tool that provides an efficient way to share state between components without the need to manually pass props. To use the ContextAPI, you need to create a Context, which stores state and provides methods for updating it. Then you must wrap the components that need to access that state with the context provider. See the example: import { createContext, useState } from 'react'; export const MyContext = createContext({}); const MyProvider = ({ children }) => { const [myState, setMyState] = useState("gbdx"); return ( <MyContext.Provider value={{ myState, setMyState }}> {children} </MyContext.Provider> ); }; export default MyProvider; This is a basic example of how to create a context with React's Context API. MyProvider is the component that will wrap the components that will have access to the context. It defines an initial state and makes it available through MyContext.Provider. To use the context value in a component, just import MyContext and use useContext, as in the example below: import { MyContext } from './MyProvider'; import React, { useContext } from 'react'; const MyComponent = () => { const { myState, setMyState } = useContext(MyContext); return ( <div> <p>{myState}</p> <button onClick={() => setMyState('new value')}> CLick to Update </button> </div> ); }; export default MyComponent; By doing so, these components can access the state and update it as needed. Additionally, the ContextAPI allows us to use scope/need-based access to context properties in our application. We can use the Context API provider in _app.js, that way the context will be provided to all components of your application that are rendered by it. This can be useful if you want to share the same context across multiple components or pages. For example, if you have a theme that you would like to apply throughout your application, you can define the Context API provider in _app.js to provide the theme for all components. On the other hand, if you define the Context API provider on a specific component, it will only be provided for that component and its children. This is useful if you have a component that needs a specific context and is not relevant to the rest of the application. import { MyProvider } from './hooks/MyProvider'; function MyApp({ Component, pageProps }) { return ( <MyProvider> <Component {...pageProps} /> </MyProvider> ); } export default MyApp; However, it is important to remember that excessive use of the ContextAPI can make the application more complex and make the code difficult to maintain. Therefore, it is essential to carefully evaluate the need to use this tool in each case. best practices Here are some best practices for working with React JS: Separation of concerns Separate code into smaller, more reusable components. Each component should have only one responsibility. This makes the code easier to understand and maintain. Dependency management Use the npm package manager to manage your project's dependencies. This makes it easy to install and update your project's dependencies. Tests Write tests to ensure your code is working correctly. Use tools like Jest and Enzyme to test React components. This helps ensure that your code is working correctly and helps reduce bugs and regression issues. Conclusion React JS is a powerful library for building user interfaces. With this guide, you should have a basic understanding to build awesome web apps. And if you want to go deeper, an amazing new official React JS documentation was created recently!

Gabriel Dürr M.

-

image: Nextjs Banner

Next.js: The React Framework of the Future

Nextjs

React.js

Framework

SSG

SSR

getStaticPaths

API-Routes

CSS Modules

Next.js is currently considered one of the most popular frameworks on the market. Thanks to its speed and robustness of resources, the framework is also known for its versatility and flexibility, very powerful and viable for creating e-commerce sites, landing pages, marketing sites, static websites and with a focus on SEO – from creation to guarantee scalability. Next.js offers resources for creating APIs within the project itself, caching, image optimization, etc. Initial setting: Create a Next.js project: npx create-next-app@latest With TypeScript add the flag --ts npx create-next-app@latest --ts NOTE: There is still the option to use a package manager (NPM, Yearn, PNPM ...): Development flow: The creation of pages happens in a very simple way, all files inside the pages folder (with the exception of config files) are transformed into pages/routes. And all files inside the API folder are turned into API routes. Styling with CSS Modules: In addition to Global styling, we have a resource called CSS modules that allows us to create styling at the component level, that is, the style is applied only within the scope of the component, without having to worry about class name conflicts in our application. It's a big plus to add a pre-processor like SASS to work together with css modules and we create cascading and more complex styles... First we must create a folder that will contain the index of the component, and create a styling file in the format file name + module.css extension, getting this way for example: input.module.css By convention and organization we use the same name as the component, adding only the module.css extension We create the styles, having each style with the class syntax: .bg { display: flex; justify-content: center; margin: 5% auto; width: 600px; height: 300px; color: #fff; background-color: #000; } We import the styling file in the default export format, a convention is to use the name styles, and we use the component's styling through React's className property, accessing the styling prop created in the module.css file. import styles from "./box-container.module.css"; type BoxContainerProps = { children?: ReactNode; }; export const BoxContainer = ({ children }: BoxContainerProps) => { return <div className={styles.bg}>{children}</div>; }; Final result: Main features of Next.js: Server-side rendering (SSR) import { GetServerSideProps } from "next"; export const getServerSideProps: GetServerSideProps = async () => { const fetchUserApi = { name: "Gabriel", alias: "gbdx", age: 23, }; return { props: { fetchUserApi, }, }; }; When using the SSR function, it will be executed with each request made on the client by the user, that is, whenever the page is opened/updated, the next.js server will look for data from an API, for example, and provide these new application data. We must use this function in cases where there is a real need, such as blocking content that can only be viewed with special access. For data that does not need to be updated with each request, we can take advantage of the generation of static pages and thus have incomparable gains in terms of page loading. Generation of static pages (SSG) import { GetStaticProps } from "next"; export const getStaticProps: GetStaticProps = async ({ params }) => { const res = await fetch(`https://site-deployed/page/${params.id}`); const data = await res.json(); return { props: { data, }, }; }; This functionality is certainly the icing on the next.js cake, with it we can generate pre-rendered static pages at build time, and thus they will be rendered by the client without the user waiting for it to load 🤩. But if there are data updates, the content is only reflected on the page by doing a new build. Generation of static pages incrementally (ISG) import { GetStaticProps } from "next"; export const getStaticProps: GetStaticProps = async ({ params }) => { const res = await fetch(`https://site-deployed/page/${params.id}`); const data = await res.json(); const thirtySeconds = 30 * 1000; return { props: { data, }, revalidate: thirtySeconds, }; }; We can generate static pages, with content being updated incrementally every period of time. That is, it will update automatically without having to do a new build so that the new data is reflected on the page. For this, we use the revalidate prop, defining the time in seconds, and next.js is responsible for updating the content whenever it reaches the defined time count Using dynamic static pages with: getStaticPaths + Static Site Generation (SSG) import { GetStaticPaths } from "next"; export const getStaticPaths: GetStaticPaths = async () => { const res = await fetch("https://site-deployed/page"); const data = await res.json(); const paths = data.map(post => ({ params: { id: post.id.toString() }, })); return { paths, fallback: false, }; }; When we need to generate static pages that are accessed dynamically through url parameters, we need to inform Next.js of all the existing routes of the application, so that when we perform the build it will create the route for all pages. To solve this problem, we use the getStaticPaths function that will be responsible for generating all the routes. This function should return an object with a property called params, and this property contains an array/list of objects. Inside each object we provide the name of the route for the property which is the same name we put in the dynamic route file, like in this example: [uid] , which could be called [slug], etc. We can retrieve the value typed in the url parameter, in the getStaticProps function and use a filter in our fetch that will fetch and generate all static pages for the uuid/slug of getStaticPaths. So we will have all pages with all routes defined statically, and this page will be displayed dynamically according to its route. import { GetStaticProps } from "next"; export const getStaticProps: GetStaticProps = async ({ params }) => { const queryApiWithParamsId = params.id; const res = await fetch(`https://site-deployed/page/${queryApiWithParamsId}`); const data = await res.json(); return { props: { data, }, }; }; Conclusion In summary, Next.js is an essential tool for developing more sophisticated React applications as it offers advanced features like SSR and SSG. With its framework optimized for scalable application development, Next.js makes building web applications even easier and more productive. If you are looking for an efficient way to create powerful React applications, visit the official NEXT.Js documentation and evolve with the framework.

Gabriel Dürr M.

-

my logo

© Designed & Built by Gabriel Dürr M. 🖤