## Szerver oldali JavaScript **13. hét** Unit és integrációs tesztek, Jest, mockolás, code coverage -- PAGE -- ### Tesztelés Miért tesztelünk? -- PAGE -- ### Tesztelés  -- PAGE -- ### Unit test Elkészítünk egy modult, egy funkciót, egy nagyon pici elemi egységet, és kíváncsiak vagyunk, fut-e: manuálisan teszteljük. Ha a kis egység működése már definiálva van, akkor az egyes szabályokra lehet teszteket írni. -- PAGE -- ### Unit test ```js function osszead(a,b){ return a + b; } ``` Mit teszteljek? - osszead(1,2) ?= 3 - osszead(2,1) ?= 3 - osszead(-1,2) ?= 1 -- PAGE -- ### Unit test Mi van, ha változik a kód? ```js function osszead(a,b){ if (a>20) return 20; return a + b; } ``` - osszead(1,2) ?= 3 - osszead(2,1) ?= 3 - osszead(-1,2) ?= 1 Kell-e működnie 20-nál nagyobb számokra az osszeadas-nak? -- PAGE -- ### Unit test  -- PAGE -- ### Integrációs teszt Ha már az építőkövek tesztelve vannak, nagyobb folyamatrészleteket / folyamatokat is lehet tesztelni. Ezt még mindig kód szintű segítséggel. -- PAGE -- ### End-to-end tesztek Felhasználó irányából megfogott, teljes folyamatot lefedő tesztek. -- PAGE -- ### Mivel tesztelünk Több javascripttesting framework is van, a 4 talán legnépszerűbb: - **Jest** - https://jestjs.io/ - **MochaJs** - https://mochajs.org/ - **QUnit** - http://qunitjs.com/ - **Jasmine** - http://jasmine.github.io/ 2024 óta a **Jest** van a tárgyban, előtte Mocha + Chai volt. A házi feladatban **Jestet** várok — `jest.fn()`-nel mockolunk, nem külön könyvtárral. -- PAGE -- ### Jest Jest egy jófajta FB termék, Frontend - Backend tesztelésre is használható. ``` npm i jest --save-dev ``` package.json: ```json "scripts": { "test": "jest" } ``` Írjunk tesztet! -- PAGE -- ### Jest unit test És egy teszteset: ```js const osszead = require('./osszead'); test('adds 1 + 2 to equal 3', () => { expect(osszead(1, 2)).toBe(3); }); ``` valami.test.js névvel -- PAGE -- ### Package.json test indítás Lefuttatni parancssorban lehet a teszteket: ``` npm run test ```  -- PAGE -- ### Eltört teszt
-- PAGE -- ### Jest Mi van, ha async amit tesztelni kell? ```js const osszead = require('./osszead'); test('adds 1 + 2 to equal 3', () => { return osszead(1, 2).then(data => { expect(data).toBe(3); }); }); ``` Promise return -- PAGE -- ### Jest Mi van, ha async amit tesztelni kell? ```js const osszead = require('./osszead'); test('adds 1 + 2 to equal 3', async() => { const data = await osszead(1, 2); expect(data).toBe(3); }); ``` Async - Await -- PAGE -- ### Szintek és pre-post funkciók ```js beforeAll(() => { /* */ }); beforeEach(() => { /* */ }); afterEach(() => { /* */ }); afterAll(() => { /* */ }); describe('group name', () => { test('test name', () => { /* */ }); test('test name', () => { /* */ }); }); ``` -- PAGE -- ### expect expect is the magic :D ```js expect(1).toBe(1); expect(1).not.toBe(2); expect(1).toEqual(1); expect(1).toBeFalsy(); expect(1).toBeDefined(); expect(1).toBeUndefined(); expect(1).toBeNull(); expect(1).toBeGreaterThan(0); expect(1).toBeLessThan(2); ``` [https://jestjs.io/docs/expect](https://jestjs.io/docs/expect) -- PAGE -- ### jest.fn() ```js const mockRandom = jest.fn(() => 42); expect(mockRandom).toHaveBeenCalled(); expect(mockRandom).toHaveBeenCalledTimes(1); expect(mockRandom).toHaveBeenCalledWith(1, 2); ``` [https://jestjs.io/docs/mock-function-api#jestfnimplementation](https://jestjs.io/docs/mock-function-api#jestfnimplementation) -- PAGE -- ### Teljes modul mockok Létezik, most NEM kell nekünk. ```js jest.mock('axios'); const axios = require('axios'); test('should fetch users', () => { const users = [{ name: 'Bob' }]; axios.get.mockResolvedValue({ data: users }); return users.fetchUsers().then(data => expect(data).toEqual(users)); }); ``` -- PAGE -- ### Hogyan is tesztelünk? Egyszerű függvényeket könnyű (require + tesztek), nézzünk meg egy middleware-t: ```js module.exports = (objRepo) => { const TorpeModel = objRepo.TorpeModel; return (req, res, next) => { return TorpeModel.find({}).then(torpek=>{ res.locals.torpek = torpek; return next(); }).catch(err=>{ return next(err); }) } } ``` -- PAGE -- ### Mockoljunk! Helyettesítsünk minden külső objektumot és dependenciát egy végletekig leegyszerűsített változattal! **Mit kell mockolni?** objRepo, req, res, res.locals, next, TorpeModel, TorpeModel.find De legalább tudjuk majd tesztelni adatbázis nélkül!!! -- PAGE -- ### Middleware teszt ```js const mw = require('loadTorpekMiddleware'); describe('loadTorpekMiddleware', () => { it('should load torpek', () => { const req = {}; const res = { locals: {} }; const next = jest.fn(); const TorpeModel = { find: jest.fn(() => Promise.resolve(['alma', 'korte'])) }; const objRepo = { TorpeModel }; const middleware = mw(objRepo); return middleware(req, res, next).then(() => { expect(res.locals.torpek).toEqual(['alma', 'korte']); expect(next).toHaveBeenCalled(); }); }); }); ``` -- PAGE -- ### Mockolni bármit ér ```js const req = { body: { email: 'user@server.com', password: 'asdasd' } }; ``` ```js const res = { send: function(){}, locals: { valamikomplex: { alma: "korte", korte: function(cb){ return this.alma; } } } }; ``` -- PAGE -- ### Code coverage
Mennyi sort, ágat, lehetőséget fed le az össze unit test.
`jest --coverage` -- PAGE --
`jest --coverage --coverageReporters=html` -- PAGE -- ### A tesztelés művészet Ezt tényleg csinálni kell, hogy meglegyen a rutin, hogy mit érdemes tesztelni, mi törhet / törik össze, mit hogyan tesztelek (hiba meglétét vs hiba szövegét).