Programovanie

Ako používať Moq na uľahčenie testovania jednotiek v C #

Často musíme napísať unit testy na kód, ktorý pristupuje k externému prostriedku, ako je napríklad databáza alebo súborový systém súborov. Ak také prostriedky nie sú k dispozícii, jediný spôsob, ako zabezpečiť, aby sa testy dali vykonať, je vytvorenie simulovaných objektov. V podstate môžete na základe falošných implementácií týchto základných závislostí vyskúšať interakciu medzi testovanou metódou a jej závislosťami. Tri z najpopulárnejších zosmiešňujúcich rámcov pre vývojárov .Net sú Rhino Mocks, Moq a NMock.

Z nich môže byť Moq najviac flexibilný a ľahko použiteľný. Rámec Moq poskytuje elegantný spôsob nastavenia, testovania a overovania falošných správ. Tento článok predstavuje diskusiu o Moq a o tom, ako sa dá použiť na izoláciu jednotiek kódu od ich závislostí.

Začíname s Moq

Môžete použiť Moq na vytvorenie falošných objektov, ktoré simulujú alebo napodobňujú skutočný objekt. MOQ je možné použiť na zosmiešnenie oboch tried a rozhraní. Existuje však niekoľko obmedzení, ktoré by ste si mali uvedomiť. Triedy, ktoré sa majú vysmievať, nemôžu byť statické ani zapečatené a vysmievaná metóda by mala byť označená ako virtuálna. (Všimnite si, že existujú obmedzenia týchto obmedzení. Statickú metódu môžete zosmiešniť napríklad tak, že využijete vzor návrhu adaptéra.)

Prvým krokom pri používaní Moq je inštalácia, aby ste ich mohli použiť v projekte testovania jednotiek. Môžete si stiahnuť Moq z GitHubu a prípadne pridať odkazy. Dávam však prednosť inštalácii Moq cez NuGet, pretože je ľahšie a menej pravdepodobné, že mu chýbajú referencie. Môžete nainštalovať Moq pomocou nasledujúceho príkazu v príkazovom riadku NuGet.

Inštalačný balík MOQ

Ako sa vysmievajú rozhraniam pomocou Moq

Začnime výsmechom rozhrania. Syntax pre vytvorenie falošného objektu pomocou triedy Mock je uvedená nižšie.

Mock mockObjectType = new Mock ();

Zvážte nasledujúce rozhranie s názvom IAuthor.

verejné rozhranie IAuthor

    {

int Id {get; sada; }

reťazec FirstName {get; sada; }

reťazec Priezvisko {get; sada; }

    }

Pomocou rámca Moq môžete vytvoriť simulovaný objekt, nastaviť hodnoty vlastností, určiť parametre a vrátiť hodnoty volaniach metód. Nasledujúci úryvok kódu ilustruje, ako môžete vytvoriť inštanciu z rozhrania IAuthor pomocou Moq.

var mock = new Mock ();

Všimnite si, že trieda Mock patrí do rámca Moq a obsahuje generický konštruktor, ktorý akceptuje typ rozhrania, ktoré chcete vytvoriť. MOQ využíva výrazy lambda, delegátov a generické výrazy. Vďaka tomu je používanie rámca veľmi intuitívne.

Nasledujúci úryvok kódu ukazuje, ako sa môžete vysmievať rozhraniu IAuthor a poskytovať vlastnosti zosmiešňovanej inštancie príslušnými hodnotami. Všimnite si, ako používame Assert na overenie hodnôt vlastností zosmiešnenej inštancie.

var autor = nový Mock ();

autor.SetupGet (p => p.Id). Návraty (1);

author.SetupGet (p => p.FirstName). Návraty („Joydip“);

author.SetupGet (p => p.LastName). Returns („Kanjilal“);

Assert.AreEqual („Joydip“, autor.Object.FirstName);

Assert.AreEqual („Kanjilal“, autor.Object.LastName);

Ako sa vysmievajú metódam pomocou Moq

Uvažujme teraz o nasledujúcej triede s názvom Article. Trieda Article obsahuje iba jednu metódu nazvanú GetPublicationDate, ktorá akceptuje ID článku ako parameter a vráti dátum zverejnenia článku.

článok verejnej triedy

    {

verejný virtuálny DateTime GetPublicationDate (int articleId)

        {

hodiť nový NotImplementedException ();

        }

    }

Pretože metóda GetPublicationDate ešte nie je implementovaná v triede Article, bola metóda zosmiešnená, aby vrátila aktuálny dátum ako dátum zverejnenia, ako je uvedené v útržku kódu uvedenom nižšie.

var mockObj = new Mock ();
mockObj.Setup (x => x.GetPublicationDate (It.IsAny ())). Returns ((int x) => DateTime.Now);

Metóda Setup sa používa na definovanie správania metódy, ktorá sa jej odovzdáva ako parameter. V tomto príklade sa používa na definovanie správania metódy GetPublicationDate. Výzva na It.IsAny () znamená, že metóda GetPublicationDate prijme parameter typu integer; To odkazuje na statickú triedu. Metóda Returns sa používa na určenie návratovej hodnoty metódy, ktorá je určená vo volaní metódy Setup. V tomto príklade sa metóda Returns používa na zadanie návratovej hodnoty metódy ako aktuálneho systémového dátumu.

Moq vám umožňuje overiť, či bola volaná konkrétna metóda alebo vlastnosť. Ilustruje to nasledujúci úryvok kódu.

mockObj.Verify (t => t.GetPublicationDate (It.IsAny ()));

Tu používame metódu Overiť na zistenie, či bol na simulovanom objekte zavolaný GetPublicationDate.

Ako sa vysmievajú metódam základnej triedy pomocou Moq

Zvážte nasledujúcu časť kódu. Máme tu dve triedy - triedu RepositoryBase a triedu AuthorRepository, ktorá ju rozširuje.

verejná abstraktná trieda RepositoryBase

{

public virtual bool IsServiceConnectionValid ()

    {

// Nejaký kód

    }

}

verejná trieda AuthorRepository: RepositoryBase

{

public void Save ()

    {

if (IsServiceConnectionValid ())

        {

// Nejaký kód

        }

    }

}

Teraz predpokladajme, že chceme skontrolovať, či je pripojenie k databáze platné. Možno však nebudeme chcieť testovať celý kód vo vnútri metódy IsServiceConnectionValid. Napríklad metóda IsServiceConnectionValid môže obsahovať kód, ktorý sa týka knižnice tretej strany. To by sme nechceli otestovať, však? Tu prichádza na pomoc metóda CallBase v Moq.

V situáciách, ako je táto, keď máte v základnej triede metódu, ktorá bola prepísaná v simulovanom type, a musíte sa vysmievať iba základnej verzii prepísanej metódy, môžete kresliť na CallBase. Nasledujúci úryvok kódu ukazuje, ako môžete vytvoriť čiastočný falošný objekt triedy AuthorRepository nastavením vlastnosti CallBase na hodnotu true.

var mockObj = new Mock () {CallBase = true};

mockObj.Setup (x => x.IsServiceConnectionValid ()). Vráti (pravda);

Rámec Moq uľahčuje vytváranie simulovaných objektov, ktoré napodobňujú správanie tried a rozhraní na testovanie, a to iba s funkčnosťou, ktorú potrebujete. Viac informácií o testovaní s predstieraním nájdete v tomto skvelom článku od Martina Fowlera.

$config[zx-auto] not found$config[zx-overlay] not found