Programmering

Hvordan enhetstest statiske metoder i C #

Når du bygger eller arbeider i .NET-applikasjoner, bruker du ofte statiske metoder. Metoder i C # kan være enten statiske eller ikke-statiske. En ikke-statisk metode (også kjent som en forekomstmetode) kan påberopes på en forekomst av klassen den tilhører. Statiske metoder trenger ikke en forekomst av klassen for å bli påkalt - de kan kalles på klassen selv.

Selv om det er greit å teste en ikke-statisk metode (i det minste en som ikke kaller en statisk metode eller samhandle med eksterne avhengigheter), er det ikke en enkel oppgave å teste en statisk metode. Denne artikkelen snakker om hvordan du kan overvinne denne utfordringen og teste statiske metoder i C #.

[Også på: Hvordan refaktorere Guds objekter i C #]

For å jobbe med kodeeksemplene som er gitt i denne artikkelen, bør du ha Visual Studio 2019 installert på systemet ditt. Hvis du ikke allerede har en kopi, kan du laste ned Visual Studio 2019 her.

Opprett et .NET Core-konsollapplikasjonsprosjekt i Visual Studio

Først og fremst, la oss lage et .NET Core Console Application-prosjekt i Visual Studio. Forutsatt at Visual Studio 2019 er installert i systemet ditt, følger du trinnene som er beskrevet nedenfor for å opprette et nytt .NET Core-konsollapplikasjonsprosjekt i Visual Studio.

  1. Start Visual Studio IDE.
  2. Klikk på "Opprett nytt prosjekt."
  3. I vinduet "Opprett nytt prosjekt" velger du "Konsollapp (.NET Core)" fra listen over maler som vises.
  4. Klikk på Neste.
  5. I vinduet “Konfigurer ditt nye prosjekt” som vises, angir du navnet og stedet for det nye prosjektet.
  6. Klikk på Opprett.

Dette vil opprette et nytt .NET Core-konsollapplikasjonsprosjekt i Visual Studio 2019. På lignende måte kan du opprette to prosjekter til - et klassebibliotek og et enhetstestprosjekt (xUnit test). Vi bruker disse tre prosjektene for å illustrere enhetstesting av statiske metoder i de påfølgende delene av denne artikkelen.

Når en statisk metode kan og ikke kan testes enhet

Enhetstesting av en statisk metode er ikke annerledes enn enhetstesting av en ikke-statisk metode. Statiske metoder er ikke uprøvbare i seg selv. En statisk metode som ikke har tilstand eller ikke endrer tilstand kan testes enhet. Så lenge metoden og dens avhengigheter er idempotent, kan metoden enhetstestes. Problemene oppstår når den statiske metoden kaller andre metoder eller når objektet som testes kaller den statiske metoden. På den annen side, hvis objektet som testes, kaller en instansemetode, kan du enkelt teste det enkelt.

En statisk metode kan ikke enhetstestes hvis noe av det følgende gjelder:

  • Den statiske metoden samhandler med eksterne avhengigheter som en database, filsystem, nettverk eller ekstern API.
  • Den statiske metoden inneholder tilstandsinformasjon, dvs. hvis den cacher data i et statisk objekt i klassen.

Tenk på følgende kodebit som viser to klasser, nemlig ProductBL og Logger. Mens ProductBL er en ikke-statisk klasse, er Logger en statisk klasse. Merk at skrivemetoden til Logger-klassen har blitt kalt fra LogMessage-metoden i ProductBL-klassen.

offentlig klasse ProductBL

    {

offentlig ugyldig LogMessage (strengmelding)

        {

Logger.Skriv (melding);

        }

    }

offentlig klasse Logger

    {

offentlig statisk tomrom Skriv (streng melding)

        {

// Skriv koden din her for å logge data

        }

    }

Anta at skrivemetoden til Logger-klassen kobles til en database og deretter skriver dataene til en databasetabell. Navnet på databasen og tabellen der dataene skal skrives kan være forhåndskonfigurert i filen appsettings.json. Hvordan kan du nå skrive enhetstester for ProductBL-metoden?

Merk at statiske metoder ikke lett kan spottes. Hvis du for eksempel har to klasser som heter A og B, og klasse A bruker et statisk medlem av klasse B, vil du ikke være i stand til å enhetstest klasse A isolert.

Tre måter å enhetsteste statiske metoder på

Du kan bruke Moq til å spotte ikke-statiske metoder, men det kan ikke brukes til å spotte statiske metoder. Selv om statiske metoder ikke kan spottes lett, er det noen måter å spotte statiske metoder på.

Du kan dra nytte av Moles eller Fakes-rammeverket fra Microsoft for å spotte statiske metodesamtaler. (Fakes-rammeverket ble inkludert i Visual Studio 2012 som etterfølgeren til Moles - det er neste generasjon Moles og Stubs.) En annen måte å spotte statiske metodesamtaler på er å bruke delegater. Det er enda en måte å spotte statiske metodesamtaler i et program - ved hjelp av omslagsklasser og avhengighetsinjeksjon.

IMHO dette siste alternativet er den beste løsningen på problemet. Alt du trenger å gjøre er å pakke den statiske metodeanropet inn i en forekomstmetode og deretter bruke avhengighetsinjeksjon for å injisere en forekomst av innpakningsklassen til klassen som testes.

Lag en wrapper-klasse i C #

Følgende kodebit illustrerer LogWrapper-klassen som implementerer IWrapper-grensesnittet og bryter et anrop til Logger.Write () -metoden i en forekomstmetode kalt LogData.

offentlig klasse LogWrapper: IWrapper

    {

streng _melding = null;

offentlig LogWrapper (strengmelding)

        {

_melding = melding;

        }

offentlig ugyldig LogData (strengmelding)

        {

_melding = melding;

Logger.Write (_melding);

        }

    }

Følgende kodebit viser IWrapper-grensesnittet. Den inneholder erklæringen om LogData-metoden.

offentlig grensesnitt IWrapper

    {

ugyldig LogData (strengmelding);

    }

ProductBL-klassen bruker avhengighetsinjeksjon (konstruktørinjeksjon) for å injisere en forekomst av LogWrapper-klassen som vist i kodelisten nedenfor.

offentlig klasse ProductBL

    {

readonly IWrapper _wrapper;

statisk streng _melding = null;

offentlig ProductBL (IWrapper wrapper)

        {

_ innpakning = innpakning;

        }

offentlig ugyldig LogMessage (strengmelding)

        {

_melding = melding;

_wrapper.LogData (_melding);

        }

    }

LogMessage-metoden i ProductBL-klassen kaller LogData-metoden på forekomsten av LogWrapper-klassen som er injisert tidligere.

Bruk xUnit og Moq til å lage en enhetstestmetode i C #

Åpne filen UnitTest1.cs og gi nytt navn til UnitTest1-klassen til UnitTestForStaticMethodsDemo. UnitTest1.cs-filene vil automatisk bli omdøpt til UnitTestForStaticMethodsDemo.cs. Vi vil nå dra nytte av Moq-rammeverket for å sette opp, teste og verifisere spott.

Følgende kodebit illustrerer hvordan du kan bruke Moq-rammeverket til enhetstestmetoder i C #.

var mock = new Mock ();

mock.Setup (x => x.LogData (It.IsAny ()));

nytt ProductBL (mock.Object) .LogMessage ("Hello World!");

mock.VerifyAll ();

Når du utfører testen, kan du se hvordan utgangen skal se ut i vinduet Testutforsker.

Den fullstendige kodelisten for testklassen er gitt nedenfor for din referanse.

offentlig klasse UnitTestForStaticMethodsDemo

    {

[Faktum]

offentlig ugyldig StaticMethodTest ()

        {

var mock = new Mock ();

mock.Setup (x => x.LogData (It.IsAny ()));

nytt ProductBL (mock.Object) .LogMessage ("Hello World!");

mock.VerifyAll ();

        }

    }

Enhetstesting er en prosess som tester enheter av kode i et program for å sjekke om de faktiske resultatene fra enhetstesten samsvarer med de ønskede resultatene. Hvis enhetlig testing blir brukt, kan det bidra til å forhindre feil i utviklingsfasen av et prosjekt.

Statiske metoder kan utgjøre en rekke problemer når du prøver å teste dem med mocks. Hvis søknaden din krever at du spotter en statisk metode, bør du vurdere at en designlukt - dvs. en indikator på dårlig design. Jeg vil diskutere narr, forfalskninger og stubber mer detaljert i en fremtidig artikkel her.

Hvordan gjøre mer i C #:

  • Hvordan refaktorere Guds objekter i C #
  • Hvordan bruke ValueTask i C #
  • Hvordan bruke uforanderlighet i C
  • Slik bruker du const, readonly og static i C #
  • Slik bruker du datanoteringer i C #
  • Hvordan jobbe med GUIDer i C # 8
  • Når skal jeg bruke en abstrakt klasse vs. grensesnitt i C #
  • Hvordan jobbe med AutoMapper i C #
  • Hvordan bruke lambdauttrykk i C #
  • Hvordan jobbe med Action-, Func- og Predicate-delegater i C #
  • Hvordan jobbe med delegater i C #
  • Slik implementerer du en enkel logger i C #
  • Hvordan jobbe med attributter i C #
  • Hvordan jobbe med log4net i C #
  • Slik implementerer du mønsteret for depotdesign i C #
  • Hvordan jobbe med refleksjon i C #
  • Hvordan jobbe med filsystemwatcher i C #
  • Hvordan utføre lat initialisering i C #
  • Hvordan jobbe med MSMQ i C #
  • Hvordan jobbe med utvidelsesmetoder i C #
  • Hvordan vi lambdauttrykk i C #
  • Når skal du bruke det flyktige nøkkelordet i C #
  • Slik bruker du avkastningsnøkkelordet i C #
  • Hvordan implementere polymorfisme i C #
  • Hvordan lage din egen oppgaveplanlegger i C #
  • Hvordan jobbe med RabbitMQ i C #
  • Hvordan jobbe med en tuple i C #
  • Utforske virtuelle og abstrakte metoder i C #
  • Hvordan bruke Dapper ORM i C #
  • Hvordan bruke flyvevekt mønster i C #
$config[zx-auto] not found$config[zx-overlay] not found