Utilizziamo i cookie per migliorare la tua esperienza sul sito
CodeWorlds

Projekt: Kompletny zestaw testów dla systemu Parku Jurajskiego

Czas na finalne wyzwanie! Zbudujesz kompletny zestaw testów dla systemu zarządzania Parkiem Jurajskim. Ten projekt łączy wszystkie koncepcje z modułu: Jest, matchery, setup/teardown, mockowanie, testowanie asynchroniczne, TDD i TypeScript.

System do przetestowania

Poniżej znajdziesz kompletny system zarządzania parkiem. Twoim zadaniem jest napisanie testów dla każdego modułu.

Moduł 1: Zarządzanie dinozaurami

1// dinosaurManager.js
2class DinosaurManager {
3  constructor() {
4    this.dinosaurs = new Map();
5    this.nextId = 1;
6  }
7
8  addDinosaur(name, species, diet, zone) {
9    if (!name || !species) {
10      throw new Error('Name and species are required');
11    }
12
13    const id = `DINO-${String(this.nextId).padStart(3, '0')}`;
14    this.nextId++;
15
16    const dinosaur = {
17      id,
18      name,
19      species,
20      diet,
21      zone,
22      health: 100,
23      fed: false,
24      lastFed: null,
25    };
26
27    this.dinosaurs.set(id, dinosaur);
28    return dinosaur;
29  }
30
31  getDinosaur(id) {
32    return this.dinosaurs.get(id) || null;
33  }
34
35  feedDinosaur(id, food) {
36    const dino = this.getDinosaur(id);
37    if (!dino) throw new Error('Dinosaur not found');
38
39    const correctFood = {
40      carnivore: 'meat',
41      herbivore: 'plants',
42      omnivore: ['meat', 'plants'],
43    };
44
45    const expected = correctFood[dino.diet];
46    const isCorrect = Array.isArray(expected)
47      ? expected.includes(food)
48      : expected === food;
49
50    if (!isCorrect) {
51      return { success: false, message: 'Wrong food type' };
52    }
53
54    dino.health = Math.min(100, dino.health + 10);
55    dino.fed = true;
56    dino.lastFed = new Date();
57
58    return { success: true, health: dino.health };
59  }
60
61  getByZone(zone) {
62    return [...this.dinosaurs.values()].filter(d => d.zone === zone);
63  }
64
65  getByDiet(diet) {
66    return [...this.dinosaurs.values()].filter(d => d.diet === diet);
67  }
68
69  getTotalCount() {
70    return this.dinosaurs.size;
71  }
72}

Moduł 2: System bezpieczeństwa

1// securitySystem.js
2class SecuritySystem {
3  constructor(alertService) {
4    this.alertService = alertService; // zależność do mockowania
5    this.zones = new Map();
6    this.logs = [];
7  }
8
9  registerZone(name, fenceVoltage, securityLevel) {
10    this.zones.set(name, {
11      name,
12      fenceVoltage,
13      securityLevel,
14      status: 'active',
15      breachCount: 0,
16    });
17  }
18
19  async reportBreach(zoneName) {
20    const zone = this.zones.get(zoneName);
21    if (!zone) throw new Error('Zone not found');
22
23    zone.breachCount++;
24    zone.status = 'breached';
25
26    this.logs.push({
27      type: 'BREACH',
28      zone: zoneName,
29      timestamp: Date.now(),
30    });
31
32    await this.alertService.sendAlert(zoneName, 'Security breach detected');
33
34    if (zone.breachCount >= 3) {
35      await this.activateLockdown(zoneName);
36    }
37
38    return { status: 'reported', breachCount: zone.breachCount };
39  }
40
41  async activateLockdown(zoneName) {
42    const zone = this.zones.get(zoneName);
43    zone.status = 'lockdown';
44    zone.fenceVoltage *= 2;
45
46    await this.alertService.sendAlert(
47      zoneName,
48      'LOCKDOWN ACTIVATED'
49    );
50
51    this.logs.push({
52      type: 'LOCKDOWN',
53      zone: zoneName,
54      timestamp: Date.now(),
55    });
56  }
57
58  getZoneStatus(zoneName) {
59    const zone = this.zones.get(zoneName);
60    return zone ? zone.status : null;
61  }
62}

Moduł 3: System monitoringu (asynchroniczny)

1// monitoringService.js
2class MonitoringService {
3  constructor() {
4    this.sensors = [];
5    this.interval = null;
6  }
7
8  addSensor(zoneId, type) {
9    this.sensors.push({
10      zoneId,
11      type,
12      status: 'online',
13      lastReading: null,
14    });
15  }
16
17  async checkSensor(index) {
18    return new Promise((resolve, reject) => {
19      setTimeout(() => {
20        if (index < 0 || index >= this.sensors.length) {
21          reject(new Error('Sensor not found'));
22          return;
23        }
24
25        const sensor = this.sensors[index];
26        sensor.lastReading = Date.now();
27
28        resolve({
29          zoneId: sensor.zoneId,
30          type: sensor.type,
31          status: sensor.status,
32          reading: Math.random() * 100,
33        });
34      }, 1000);
35    });
36  }
37
38  startMonitoring(callback, intervalMs) {
39    this.interval = setInterval(() => {
40      const readings = this.sensors.map(s => ({
41        zone: s.zoneId,
42        status: s.status,
43      }));
44      callback(readings);
45    }, intervalMs);
46  }
47
48  stopMonitoring() {
49    if (this.interval) {
50      clearInterval(this.interval);
51      this.interval = null;
52    }
53  }
54}

Twoje zadanie

Napisz kompletny zestaw testów obejmujący:

  1. DinosaurManager - testy jednostkowe z beforeEach, testowanie wyjątków
  2. SecuritySystem - mockowanie alertService, testowanie async
  3. MonitoringService - fake timers, testowanie callbacków i Promise
  4. Testy integracyjne - współpraca między modułami

Pamiętaj o wzorcu AAA (Arrange-Act-Assert) i zasadach TDD!

Vai a CodeWorlds