Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 25 additions & 56 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@
"format": "prettier --write \"src/**/*.ts\"",
"lint": "eslint \"src/**/*.ts\" --fix",
"test": "jest --silent",
"test1": "npx jest src/01-simple-tests/index.test.ts ",
"test2": "npx jest src/02-table-tests/index.test.ts ",
"test3": "npx jest src/03-error-handling-async/index.test.ts ",
"test4": "npx jest src/04-test-class/index.test.ts ",
"test5": "npx jest src/05-partial-mocking/index.test.ts ",
"test6": "npx jest src/06-mocking-node-api/index.test.ts ",
"test7": "npx jest src/07-mocking-lib-api/index.test.ts ",
"test8": "npx jest src/08-snapshot-testing/index.test.ts ",
"test:verbose": "jest",
"build": "tsc"
},
Expand Down
24 changes: 16 additions & 8 deletions src/01-simple-tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,40 @@
// Uncomment the code below and write your tests
// import { simpleCalculator, Action } from './index';
import { describe, test, expect } from '@jest/globals';
import { simpleCalculator, Action } from './index';

describe('simpleCalculator tests', () => {
test('should add two numbers', () => {
// Write your test here
const res = simpleCalculator({ a: 1, b: 2, action: Action.Add });
expect(res).toBe(3);
});

test('should subtract two numbers', () => {
// Write your test here
const res = simpleCalculator({ a: 5, b: 1, action: Action.Subtract });
expect(res).toBe(4);
});

test('should multiply two numbers', () => {
// Write your test here
const res = simpleCalculator({ a: 10, b: 2, action: Action.Multiply });
expect(res).toBe(20);
});

test('should divide two numbers', () => {
// Write your test here
const res = simpleCalculator({ a: 15, b: 3, action: Action.Divide });
expect(res).toBe(5);
});

test('should exponentiate two numbers', () => {
// Write your test here
const res = simpleCalculator({ a: 9, b: 2, action: Action.Exponentiate });
expect(res).toBe(81);
});

test('should return null for invalid action', () => {
// Write your test here
const res = simpleCalculator({ a: 2, b: 2, action: true });
expect(res).toBeNull();
});

test('should return null for invalid arguments', () => {
// Write your test here
const res = simpleCalculator({ a: true, b: 'a', action: Action.Add });
expect(res).toBeNull();
});
});
35 changes: 24 additions & 11 deletions src/02-table-tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
// Uncomment the code below and write your tests
/* import { simpleCalculator, Action } from './index';
import { simpleCalculator, Action } from './index';
import { describe, test, expect } from '@jest/globals';

const testCases = [
{ a: 1, b: 2, action: Action.Add, expected: 3 },
{ a: 2, b: 2, action: Action.Add, expected: 4 },
{ a: 3, b: 2, action: Action.Add, expected: 5 },
// continue cases for other actions
]; */
{ a: 1, b: 2, action: Action.Add, expected: 3 },
{ a: 2, b: 2, action: Action.Add, expected: 4 },
{ a: 3, b: 2, action: Action.Add, expected: 5 },
{ a: 10, b: 2, action: Action.Divide, expected: 5 },
{ a: 15, b: 5, action: Action.Divide, expected: 3 },
{ a: 36, b: 6, action: Action.Divide, expected: 6 },
{ a: 5, b: 2, action: Action.Exponentiate, expected: 25 },
{ a: 3, b: 3, action: Action.Exponentiate, expected: 27 },
{ a: 7, b: 3, action: Action.Exponentiate, expected: 343 },
{ a: 4, b: 5, action: Action.Multiply, expected: 20 },
{ a: 3, b: 10, action: Action.Multiply, expected: 30 },
{ a: 6, b: 4, action: Action.Multiply, expected: 24 },
{ a: 30, b: 5, action: Action.Subtract, expected: 25 },
{ a: 18, b: 9, action: Action.Subtract, expected: 9 },
{ a: 40, b: 5, action: Action.Subtract, expected: 35 },
];

describe('simpleCalculator', () => {
// This test case is just to run this test suite, remove it when you write your own tests
test('should blah-blah', () => {
expect(true).toBe(true);
});
// Consider to use Jest table tests API to test all cases above
test.each(testCases)(
'the result of $action for $a and $b is $expected',
({ a, b, action, expected }) => {
expect(simpleCalculator({ a, b, action })).toBe(expected);
},
);
});
36 changes: 29 additions & 7 deletions src/03-error-handling-async/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,52 @@
// Uncomment the code below and write your tests
// import { throwError, throwCustomError, resolveValue, MyAwesomeError, rejectCustomError } from './index';
import {
throwError,
throwCustomError,
resolveValue,
MyAwesomeError,
rejectCustomError,
} from './index';
import { describe, test, expect } from '@jest/globals';

describe('resolveValue', () => {
test('should resolve provided value', async () => {
// Write your test here
const testValues = [
'test string',
42,
{ key: 'value' },
[1, 2, 3],
null,
undefined,
];
for (const value of testValues) {
await expect(resolveValue(value)).resolves.toBe(value);
}
});
});

describe('throwError', () => {
test('should throw error with provided message', () => {
// Write your test here
const customMessage = 'Custom error message';
expect(() => throwError(customMessage)).toThrow(customMessage);
expect(() => throwError(customMessage)).toThrow(Error);
});

test('should throw error with default message if message is not provided', () => {
// Write your test here
expect(() => throwError()).toThrow('Oops!');
expect(() => throwError(undefined)).toThrow('Oops!');
});
});

describe('throwCustomError', () => {
test('should throw custom error', () => {
// Write your test here
expect(() => throwCustomError()).toThrow(MyAwesomeError);
expect(() => throwCustomError()).toThrow(
'This is my awesome custom error!',
);
});
});

describe('rejectCustomError', () => {
test('should reject custom error', async () => {
// Write your test here
await expect(rejectCustomError()).rejects.toThrow(MyAwesomeError);
});
});
114 changes: 102 additions & 12 deletions src/04-test-class/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,134 @@
// Uncomment the code below and write your tests
// import { getBankAccount } from '.';
import {
InsufficientFundsError,
SynchronizationFailedError,
TransferFailedError,
getBankAccount,
} from '.';
import { describe, test, expect } from '@jest/globals';
import { random } from 'lodash';

jest.mock('lodash', () => ({
random: jest.fn(),
}));

describe('BankAccount', () => {
beforeEach(() => {
jest.clearAllMocks();
});
test('should create account with initial balance', () => {
// Write your test here
const initialBalance = 1000;
const account = getBankAccount(initialBalance);

expect(account.getBalance()).toBe(initialBalance);
});

test('should throw InsufficientFundsError error when withdrawing more than balance', () => {
// Write your test here
const initialBalance = 500;
const account = getBankAccount(initialBalance);
const withdrawAmount = 600;

expect(() => account.withdraw(withdrawAmount)).toThrow(
InsufficientFundsError,
);
expect(() => account.withdraw(withdrawAmount)).toThrow(
`Insufficient funds: cannot withdraw more than ${initialBalance}`,
);
});

test('should throw error when transferring more than balance', () => {
// Write your test here
const account1 = getBankAccount(500);
const account2 = getBankAccount(100);
const transferAmount = 600;

expect(() => account1.transfer(transferAmount, account2)).toThrow(
InsufficientFundsError,
);
});

test('should throw error when transferring to the same account', () => {
// Write your test here
const account = getBankAccount(1000);
const transferAmount = 100;

expect(() => account.transfer(transferAmount, account)).toThrow(
TransferFailedError,
);
expect(() => account.transfer(transferAmount, account)).toThrow(
'Transfer failed',
);
});

test('should deposit money', () => {
// Write your test here
const initialBalance = 1000;
const depositAmount = 500;
const account = getBankAccount(initialBalance);

account.deposit(depositAmount);

expect(account.getBalance()).toBe(initialBalance + depositAmount);
});

test('should withdraw money', () => {
// Write your test here
const initialBalance = 1000;
const withdrawAmount = 300;
const account = getBankAccount(initialBalance);

account.withdraw(withdrawAmount);

expect(account.getBalance()).toBe(initialBalance - withdrawAmount);
});

test('should transfer money', () => {
// Write your test here
const initialBalance1 = 1000;
const initialBalance2 = 500;
const transferAmount = 300;

const account1 = getBankAccount(initialBalance1);
const account2 = getBankAccount(initialBalance2);

account1.transfer(transferAmount, account2);

expect(account1.getBalance()).toBe(initialBalance1 - transferAmount);
expect(account2.getBalance()).toBe(initialBalance2 + transferAmount);
});

test('fetchBalance should return number in case if request did not failed', async () => {
// Write your tests here
const account = getBankAccount(1000);
const mockBalance = 42;
(random as jest.Mock)
.mockReturnValueOnce(mockBalance)
.mockReturnValueOnce(1);

const result = await account.fetchBalance();

expect(result).toBe(mockBalance);
expect(random).toHaveBeenCalledTimes(2);
});

test('should set new balance if fetchBalance returned number', async () => {
// Write your tests here
const initialBalance = 1000;
const newBalance = 750;
const account = getBankAccount(initialBalance);

(random as jest.Mock)
.mockReturnValueOnce(newBalance)
.mockReturnValueOnce(1);

await account.synchronizeBalance();

expect(account.getBalance()).toBe(newBalance);
expect(account.getBalance()).not.toBe(initialBalance);
});

test('should throw SynchronizationFailedError if fetchBalance returned null', async () => {
// Write your tests here
const account = getBankAccount(1000);

(random as jest.Mock).mockReturnValueOnce(100).mockReturnValueOnce(0);

await expect(account.synchronizeBalance()).rejects.toThrow(
SynchronizationFailedError,
);
await expect(account.synchronizeBalance()).rejects.toThrow(
'Synchronization failed',
);
});
});
29 changes: 24 additions & 5 deletions src/05-partial-mocking/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
// Uncomment the code below and write your tests
// import { mockOne, mockTwo, mockThree, unmockedFunction } from './index';
import { mockOne, mockTwo, mockThree, unmockedFunction } from './index';

jest.mock('./index', () => {
// const originalModule = jest.requireActual<typeof import('./index')>('./index');
const originalModule =
jest.requireActual<typeof import('./index')>('./index');
return {
...originalModule,
mockOne: jest.fn(),
mockTwo: jest.fn(),
mockThree: jest.fn(),
};
});

describe('partial mocking', () => {
Expand All @@ -11,10 +17,23 @@ describe('partial mocking', () => {
});

test('mockOne, mockTwo, mockThree should not log into console', () => {
// Write your test here
const consoleSpy = jest.spyOn(console, 'log');
mockOne();
mockTwo();
mockThree();

expect(consoleSpy).not.toHaveBeenCalled();

consoleSpy.mockRestore();
});

test('unmockedFunction should log into console', () => {
// Write your test here
const consoleSpy = jest.spyOn(console, 'log');

unmockedFunction();

expect(consoleSpy).toHaveBeenCalledWith('I am not mocked');

consoleSpy.mockRestore();
});
});
Loading