TypeScript is an open - source programming language developed and maintained by Microsoft. It adds static typing to JavaScript, which means that variables, function parameters, and return values can have types assigned to them. This helps in catching type - related errors during development, making the code more reliable and easier to understand and maintain. For example:
// A simple TypeScript function with typed parameters and return value
function add(a: number, b: number): number {
return a + b;
}
const result = add(3, 5);
console.log(result);
Jest is a JavaScript testing framework developed by Facebook. It is designed to be easy to set up and use, with a zero - configuration approach for many projects. Jest comes with built - in support for snapshot testing, mocking, and code coverage reporting. It can be used to test both JavaScript and TypeScript code.
First, create a new directory for your project and initialize it with npm
or yarn
.
mkdir typescript-jest-project
cd typescript-jest-project
npm init -y
Install TypeScript, Jest, and the necessary TypeScript types for Jest.
npm install --save-dev typescript jest @types/jest ts-jest
Create a tsconfig.json
file to configure TypeScript.
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
Create a jest.config.js
file to configure Jest to work with TypeScript.
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
Create a simple TypeScript file, for example, math.ts
.
export function multiply(a: number, b: number): number {
return a * b;
}
Create a test file with the same name as the file you want to test, but with a .test.ts
extension, e.g., math.test.ts
.
import { multiply } from './math';
test('multiply function should multiply two numbers correctly', () => {
const result = multiply(2, 3);
expect(result).toBe(6);
});
You can test more complex functions, including those with conditional logic.
// utils.ts
export function isEven(num: number): boolean {
return num % 2 === 0;
}
// utils.test.ts
import { isEven } from './utils';
test('isEven should return true for even numbers', () => {
expect(isEven(4)).toBe(true);
});
test('isEven should return false for odd numbers', () => {
expect(isEven(3)).toBe(false);
});
Create a simple class in TypeScript and write tests for its methods.
// person.ts
export class Person {
constructor(private name: string, private age: number) {}
getDetails(): string {
return `Name: ${this.name}, Age: ${this.age}`;
}
}
// person.test.ts
import { Person } from './person';
test('getDetails method should return correct details', () => {
const person = new Person('John', 30);
const details = person.getDetails();
expect(details).toBe('Name: John, Age: 30');
});
It is a good practice to organize your tests in a way that mirrors your project structure. For example, if you have a src
directory with multiple sub - directories for different modules, create a __tests__
directory at the same level as each module and place the test files there.
Mocking is useful when you want to isolate a unit of code from its dependencies.
// api.ts
export async function fetchData() {
const response = await fetch('https://example.com/api/data');
return response.json();
}
// api.test.ts
import { fetchData } from './api';
jest.mock('node-fetch');
import fetch from 'node-fetch';
test('fetchData should call the API and return data', async () => {
const mockData = { message: 'Mocked data' };
(fetch as jest.Mock).mockResolvedValue({
json: jest.fn().mockResolvedValue(mockData),
});
const result = await fetchData();
expect(result).toEqual(mockData);
});
When testing asynchronous code, use async/await
or the done
callback in Jest.
// asyncUtils.ts
export async function asyncAdd(a: number, b: number): Promise<number> {
return new Promise((resolve) => {
setTimeout(() => {
resolve(a + b);
}, 100);
});
}
// asyncUtils.test.ts
import { asyncAdd } from './asyncUtils';
test('asyncAdd should add two numbers asynchronously', async () => {
const result = await asyncAdd(2, 3);
expect(result).toBe(5);
});
Design your code in a way that is easy to test. This includes keeping functions and classes small and focused, using dependency injection, and avoiding global state.
Integrate Jest with your CI/CD pipeline, such as GitHub Actions or GitLab CI. This ensures that your tests are run automatically whenever there are changes to your codebase.
# .github/workflows/main.yml
name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs - on: ubuntu - latest
steps:
- uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup - node@v2
with:
node - version: '14'
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test
TypeScript and Jest are a powerful combination for modern web development. TypeScript helps in writing more reliable code by adding static typing, while Jest simplifies the testing process with its user - friendly API and built - in features. By following the concepts, usage methods, common practices, and best practices outlined in this blog post, you can write high - quality, testable TypeScript code and ensure the stability of your applications.