Kuinka pilkata ES6-luokkaa

Tämän viestin tarkoituksena on näyttää kuinka pilkata luokkaa JavaScriptillä yksikkötestausta varten. Viesti on suunnattu kehittäjille, jotka tulevat ES6: een ympäristöistä, joissa on ominaisuuksia, kuten riippuvuuden injektio ja rajapinnat. Suurin osa viestistä kattaa sen, mikä on luokka ES6: ssa ja miksi me niitä tarvitsemme. Kun perustana oleva malli on peitetty, sen pilkaaminen on ilmeistä. Tämä viesti vie sinut läpi objektien luomisen JavaScriptiin.

Object Literal

Objekti on ensimmäinen kansalainen JavaScript-maassa. Hämmästyttävän helppo tapa luoda objekti tekee tämän kielen aloittamisen helpoksi. Tässä on näyteobjekti.

var henkilö = {
  nimi: 'Velu'
};

Se on tämä yksinkertainen. Objektin luomiseksi aloitat objektilla (eikä luokalla). Tältä osin väittäisin, että JavaScript on totta oliopohjaista (ja Java-kaltaiset kielet ovat luokkaorientoituneita, kun aloitat luokan luomaan objekteja).

Laajennetaan yllä olevaa esimerkkiä lisätäksesi käyttäytymisen esimerkkiobjektiimme, sayName.

var henkilö1 = {
  nimi: 'Velu',
  sayName: function () {
    console.log (this.name);
  }
}

Tämän objektin kanssa, jos haluat luoda useita objekteja, sinun on kopioitava sanotun nimen toiminto jokaisessa objektissa. Tämä tarkoittaisi:

var henkilö1 = {
  nimi: 'Velu',
  sayName: function () {
    console.log (this.name);
  }
}
var person2 = {
  nimi: 'Raj',
  sayName: function () {
    console.log (this.name);
  }
}

Jos päädyt luomaan monia ihmisiä, tämä tarkoittaisi, että koodin päällekkäisyyttä on paljon. Tämän voittamiseksi tulee konstruktoritoiminto.

Konstruktoritoiminto

Olkaamme kirjoittaa näyte konstruktoritoiminnosta ja puhua siitä:

tehtävä Henkilö (nimi) {
  tämä.nimi = nimi;
  this.sayName = toiminto () {
    console.log (this.name);
  }
}

Ensi silmäyksellä tämä on jälleen yksi JavaScript-toiminto. Mikä tekee konstruktoritoiminnasta erityisen, ei ole itse toiminto, vaan silloin, kun se yhdistetään uuteen avainsanaan. Joten rakentajatoimintoa voidaan käyttää kuten:

var henkilö1 = uusi henkilö ('Velu');

Yllä oleva rivi luo objektin ja kirjaimellisesti koodi muutetaan:

var henkilö1 = {
  nimi: 'Velu',
  sayName: function () {
    console.log (this.name);
  }
}

Nyt uusien ihmisten luomiseen ei ole päällekkäisyyttä. Suunnitelma on määritelty Constructor Function -toiminnossa, ja JavaScript muuntaa taianomaisesti objektin muotoon suoritusaikana.

Tällä ei ole koodin päällekkäisyyttä, mutta taustalla olevalla esineellä on silti kopiokappale. SayName-funktio määritetään vain kerran rakennusfunktiossa, mutta se kopioidaan silti jokaisessa luomassa objektissa. Tämä tarkoittaa enemmän muistia. Esimerkiksi jos luon 1 miljardia ihmistä Mac Book Pro -sovellukseen, solmuprosessi kaatuu, kun muistia ei ole. Tämä tuo tarvetta jakaa kohdemalli paitsi koodiaikana myös suorituksen aikana.

Prototyyppi

Joten tarvitsemme mekanismia toimintojen jakamiseen objektien välillä. JavaScriptissä koodin jakamismekanismi on jälleen yksi prototyyppi nimeltään objekti. Jokaisella luodulla JavaScript-objektilla on sisäänrakennettu linkki nimeltään prototyyppi toiseen objektiin. Tämä objekti jaetaan kaikille objekteille, jotka on luotu samalla Constructor Function -toiminnolla. Alla oleva asettelu kuvaa tätä:

Nyt itsestään selvä vaihe on siirtää sayName-funktio objektista prototyyppiin. Koodin alapuolella tämä tapahtuu:

tehtävä Henkilö (nimi) {
  tämä.nimi = nimi;
}
Person.prototype.sayName = function () {
    console.log (this.name);
}

Lisäksi JavaScript varmistaa seuraavien kahden asian tekemisen, jotta se olisi mahdollista:

  1. Jos omaisuuteen pääsee objektissa eikä sitä ole siinä objektissa, se etsitään ja otetaan käyttöön sen prototyypissä
  2. "Tämä" viittaus prototyyppiin liitettyihin toimintoihin, jotka on taianomaisesti sidottu kohteeseen, johon se vedotaan

Joten alla sanottu nameName-kutsuminen on varmistettu, että tämä osoittaa henkilölle1 esineen suorituksen aikana.

var henkilö1 = uusi henkilö ('Velu');
person1.sayName ();

ES6-luokka

Nyt tulossa ES6-luokkaan on viimeinkin vain syntaattinen sokeri, joka tuottaa konstruktoritoiminnon ajon aikana. Luokan syntaksi tuo tämän vain tiiviimmin:

luokan henkilö {
  rakentaja (nimi) {
    tämä.nimi = nimi;
  }
  sayName () {
    console.log (this.name);
  }
}

Ymmärrettyään, mikä ES6-luokka on konepellin alla, on vielä yksi JavaScript-käsite ymmärrettäväksi. Harkitse seuraavia JavaScriptiä ja sen riippuvuuksia:

Tässä rakenteessa moduuli A tuo sekä B että C. Nyt kun moduuli B tuo myös C: tä, A: n lataama moduuli käytetään uudelleen eikä ole uusi. Tämä tarkoittaa, että jos ES6-luokka viedään moduulista C, sen määritelmää voidaan muuttaa A: ssä ja muutettu määritelmä heijastuu C: ssä. Tämän ES6-luokkien ja moduulijärjestelmän ymmärtämisen avulla voimme lopulta nähdä kuinka pilkata.

ES6-luokan pilkkaaminen

Tarkastellaan seuraavaa testiskenaariota. Työntekijä on riippuvainen apuohjelmaluokan auttajasta saadaksesi satunnaisluvun. Työntekijämoduuli näyttää seuraavalta:

const Helper = vaadi ('./ helper');

luokan työntekijä {
  rakentaja (nimi) {
    tämä.nimi = nimi;
  }

  getId () {
    const helper = uusi auttaja ();
    const id = helper.getRandom ();

    palauta `$ {tämä.nimi} - $ {id}`;
  }
}

module.exports = Työntekijä;

Työntekijän yksikkötesti on pilkata getRandom-menetelmää testin johtamiseksi Employee.getId-sivustolla. Virtaus näyttää seuraavalta:

Nyt kaikilla tähän mennessä kerättyillä yksityiskohdilla pilkkauskoodi on ilmeinen ja se kuuluu:

const odottaa = vaadi ('chai'). odota;
const sinon = vaadi ('sinon');

const Työntekijä = vaadi ('../ src / työntekijä');
const Helper = vaadi ('../src / helper');

kuvaile ('työntekijän testi', () => {
  se ('pitäisi palauttaa oikea tunnus', () => {
    // Järjestää
    sinon.stub (Helper.prototyyppi, 'getRandom'). aicinaFake (() => 1);

    // Laki
    const työntekijä = uusi työntekijä ('Velu');
    const id = työntekijä.getId ();

    // Väite
    odottaa (id) .to.equals (Vsfa-1 ');
  });
});

Periaatteessa menetelmän pilkkaamiseksi Helper-luokasta saadaan funktion viite luokan prototyypin kautta ja samaan tapaan. Tämä rivi estää getRandom-funktiota palauttamaan aina 1, jotta Employee.getId-toiminto voidaan vahvistaa.

sinon.stub (Helper.prototyyppi, 'getRandom'). aicinaFake (() => 1);

Koodikanta tähän löytyy https://github.com/madhanganesh/es6-class-mocking-sample