Programavimas

Kaip naudoti „Moq“ norint palengvinti vieneto bandymą C #

Mes dažnai turime parašyti kodo, kuris pasiekia išorinį šaltinį, pvz., Duomenų bazę ar failų failų sistemą, vieneto testus. Jei tokių išteklių nėra, vienintelis būdas įsitikinti, kad bandymai gali būti vykdomi, yra sukūrę bandomuosius objektus. Iš esmės, pasitelkę netikrą šių pagrindinių priklausomybių įgyvendinimą, galite išbandyti sąveiką tarp bandomo metodo ir jo priklausomybių. Trys populiariausios „.Net“ kūrėjų tyčiojančios sistemos yra „Rhino Mocks“, „Moq“ ir „NMock“.

Tarp jų „Moq“ gali būti lankstiausias ir patogiausias naudoti. „Moq“ sistema suteikia elegantišką būdą nustatyti, išbandyti ir patikrinti pašaipas. Šiame straipsnyje pateikiama Moq diskusija ir kaip ji gali būti naudojama norint atskirti kodo vienetus nuo jų priklausomybės.

Darbo su Moq pradžia

Galite naudoti „Moq“, kad sukurtumėte tyčinius objektus, kurie imituoja ar imituoja tikrą objektą. Moq gali būti naudojamas tyčiotis tiek iš klasių, tiek iš sąsajų. Tačiau turėtumėte žinoti keletą apribojimų. Kursai, iš kurių tyčiojamasi, negali būti statiški ar antspauduoti, o metodas, iš kurio tyčiojamasi, turėtų būti pažymėtas kaip virtualus. (Atkreipkite dėmesį, kad yra šių apribojimų būdų. Galite pasityčioti iš statinio metodo, pasinaudodami, pavyzdžiui, adapterio dizaino modeliu.)

Pirmasis „Moq“ naudojimo žingsnis yra jo įdiegimas, kad galėtumėte jį naudoti vieneto bandymo projekte. Galite atsisiųsti „Moq“ iš „GitHub“ ir, jei reikia, pridėti nuorodų. Tačiau aš norėčiau įdiegti „Moq“ per „NuGet“, nes tai lengviau ir rečiau praleisti nuorodas. „Moq“ galite įdiegti naudodami šią komandą „NuGet“ komandų eilutėje.

„Install-Package Moq“

Kaip tyčiotis iš sąsajų naudojant Moq

Pradėkime nuo sąsajos pašiepimo. Toliau pateikiama maketo objekto kūrimo sintaksė naudojant „Mock“ klasę.

Mock mockObjectType = naujas Mock ();

Dabar apsvarstykite šią sąsają, pavadintą „IAuthor“.

viešoji sąsaja „IAuthor“

    {

int Id {gauti; rinkinys; }

eilutė FirstName {get; rinkinys; }

eilutė LastName {get; rinkinys; }

    }

Naudodami „Moq“ struktūrą, galite sukurti bandomąjį objektą, nustatyti ypatybių reikšmes, nurodyti parametrus ir grąžinti metodo iškvietimų reikšmes. Šis kodo fragmentas parodo, kaip galite sukurti egzempliorių iš „IAuthor“ sąsajos naudodami „Moq“.

var pasityčioti = naujas pasityčiojimas ();

Atkreipkite dėmesį, kad „Mock“ klasė priklauso „Moq“ sistemai ir joje yra bendras konstruktorius, kuris priima norimo sukurti sąsajos tipą. Moq naudojasi lambda išraiškomis, atstovais ir generikais. Visa tai leidžia naudoti sistemą labai intuityviai.

Šis kodo fragmentas parodo, kaip galite tyčiotis iš „IAuthor“ sąsajos ir pateikti išjuokto egzemplioriaus ypatybes su atitinkamomis reikšmėmis. Atkreipkite dėmesį, kaip mes naudojame „Assert“, kad patikrintume išjuokto egzemplioriaus savybių vertes.

var autorius = naujas pasityčiojimas ();

autorius.SetupGet (p => p.Id) .Grąžina (1);

autorius.SetupGet (p => p.Vardas) .Grąžina („Joydip“);

author.SetupGet (p => p.LastName) .Grąžina („Kanjilal“);

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

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

Kaip tyčiotis iš metodų naudojant Moq

Dabar apsvarstykime šią klasę, pavadintą Straipsnis. Straipsnio klasėje yra tik vienas metodas, vadinamas „GetPublicationDate“, kuris priima straipsnio ID kaip parametrą ir grąžina straipsnio paskelbimo datą.

visuomenės klasės straipsnis

    {

viešas virtualus „DateTime“ „GetPublicationDate“ (int ArticleId)

        {

mesti naują NotImplementedException ();

        }

    }

Kadangi „GetPublicationDate“ metodas dar neįgyvendintas straipsnių klasėje, metodas buvo pasityčiotas, kad dabartinė data būtų grąžinta kaip paskelbimo data, kaip parodyta toliau pateiktame kodo fragmente.

var mockObj = naujas Mock ();
mockObj.Setup (x => x.GetPublicationDate (It.IsAny ())). Grąžina ((int x) => DateTime.Now);

Sąrankos metodas naudojamas apibrėžti metodo, kuris jam perduodamas kaip parametras, elgseną. Šiame pavyzdyje jis naudojamas apibrėžti „GetPublicationDate“ metodo elgseną. Kvietimas It.IsAny () reiškia, kad metodas GetPublicationDate priims sveiko skaičiaus parametrą; Tai reiškia statinę klasę. Grąžinimo metodas naudojamas nurodant metodo grąžinimo vertę, nurodytą sąrankos metodo kvietime. Šiame pavyzdyje grąžinimo metodas naudojamas nurodant metodo grąžinimo vertę kaip dabartinę sistemos datą.

Moq leidžia patikrinti, ar buvo iškviestas konkretus metodas ar ypatybė. Tai iliustruoja šis kodo fragmentas.

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

Čia mes naudojame metodą „Patvirtinti“, kad nustatytume, ar „GetPublicationDate“ buvo iškviestas ant maketo objekto.

Kaip tyčiotis iš pagrindinės klasės metodų naudojant Moq

Apsvarstykite šį kodo fragmentą. Čia turime dvi klases - „RepositoryBase“ klasę ir ją pratęsiančią „AuthorRepository“ klasę.

viešoji abstrakčioji klasė „RepositoryBase“

{

viešoji virtuali „Bool“ „IsServiceConnectionValid“ ()

    {

// Kažkas kodas

    }

}

public class AuthorRepository: RepositoryBase

{

public void Išsaugoti ()

    {

jei (IsServiceConnectionValid ())

        {

// Kažkas kodas

        }

    }

}

Dabar tarkime, kad norime patikrinti, ar duomenų bazės ryšys galioja. Tačiau galbūt nenorime išbandyti viso „IsServiceConnectionValid“ metodo kodo. Pavyzdžiui, „IsServiceConnectionValid“ metode gali būti kodas, susijęs su trečiosios šalies biblioteka. Mes nenorėtume to išbandyti, tiesa? Čia gelbsti „MoB“ esantis „CallBase“ metodas.

Tokiose situacijose, kai turite bazinės klasės metodą, kuris buvo nepaisytas tyčiojamo tipo, ir jums reikia tyčiotis tik iš pagrindinio pakeisto metodo versijos, galite pasinaudoti „CallBase“. Šis kodo fragmentas parodo, kaip galite sukurti dalinį „AuthorRepository“ klasės maketo objektą nustatydami „CallBase“ ypatybę į „true“.

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

mockObj.Setup (x => x.IsServiceConnectionValid ()). Grąžina (true);

„Moq“ sistema leidžia lengvai sukurti bandomuosius objektus, imituojančius klasių ir sąsajų elgesį, kad būtų galima išbandyti, tik su jums reikalinga funkcija. Norėdami sužinoti daugiau apie bandymus su bandymais, peržiūrėkite šį puikų Martin Fowler straipsnį.