.NET MAUI – Forget Me Not – 7 – Unit Testing

Picking up where we left off, I want to add unit tests to my program. Now, I know, I should have been using unit tests all along. I have no excuse and hang my head in shame.

To get started, I’ve decided to add xUnit through NuGet. Easy peasy. But it won’t work. The full explanation is here. Great article. Here, in a nutshell are the steps you need to perform:

  1. Create an xUnit test project in the same solution as ForgetMeNot
  2. Make sure it runs
  3. Add a reference to the ForgetMeNot project
  4. This wil not run yet. Here is where the fun begins
  5. First, open up the ForgetMeNot project and change the TargetFrameworks to
<TargetFrameworks>net6.0;net6.0-android;net6.0-ios;net6.0-maccatalyst</TargetFrameworks>

6. Replace the output statement with

<OutputType Condition="'$(TargetFramework)' != 'net6.0'">Exe</OutputType>

7. Unload ForgetMeNot, reload it, close Visual Studio, open Visual Studio and voila! it will work

(The whys and wherefores are explained very well in the article referenced above)

NSubstitute for mocking

We are now almost ready to begin. I want to use mocking from the very beginning. Until about a weak ago, I’d have installed Moq, but I’m intrigued by NSubstitute, so I’m going to use that.

After assuring myself that the default xUnit test works, I’ll add a file called BuddyTests. In there I will add my first test: ShouldPopulateBuddies. I want to make sure that calling Init() will populate the list of buddies (actually, it could return no buddies, but right now I just want to get this test working).

 [Fact]
 public async Task ShouldPopulateBuddies()
 {
     var buddies = new List<Buddy>();
     var buddy = new Buddy();
     buddies.Add(buddy);
     var buddyService = Substitute.For<IBuddyService>();
     buddyService.GetBuddies().Returns(buddies);
     var buddyListVM = new BuddyListViewModel(buddyService);
     await buddyListVM.Init();
     Assert.True( buddyListVM.Buddies?.Count > 0);

 }

So what is going on here? First I create an empty list of Buddy objects and I create an instance of Buddy which I add to that list.

Next (and here is the cool part) I create a mock for my service with that one line

var buddyService = Substitute.For<IBuddyService>();

Remember that Substitute wants interfaces, so earlier I went to each class in my services, put the cursor on the class name and used Refactor->Extract->ExtractInterface which brought up this wonderful dialog box:

You are using Resharper, right??

I clicked on Select Public to get the public methods and Its own file to put the new interface in a file named IBuddyService.cs. R# is even nice enough to tack the interface name onto the class declaration.

OK, enough digression. My next step is to tell the mock that when the BuddyService’s GetBuddies method is returned, it should return the list of Buddies we just created.

We are now ready to create an instance of the ViewModel and call init() on it. It will use the service we passed in (the mock) and will thus populate its list of buddies with our dummy list and the Assert will pass.

Cool, eh?

This also tells me that I need to handle the case when the list is empty. That means I need to look long and hard at Init() and possibly add another test to prove that the corner case does not cause a problem.

Wrapping Up

It turns out that simple unit tests with mocking is not all that hard to do; and nSubstitute has a lot less ceremony than Moq. I’m going to stay with it for a while and see if I run off a cliff.

Since all the source code changes are already in this blog post, I won’t update the online source until I’ve written some more tests.

Shout-out to Daniel Hindrikes for helping me get started on unit testing for MAUI

See next posting for more unit testing using Fluent asserts.

Unknown's avatar

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. Liberty is a Senior AI Engineer at the University of Pittsburgh Medical Center, and was a Team Lead and Senior Software Engineer for various corporations, a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a 21 year Microsoft MVP.
This entry was posted in .NET MAUI, Essentials, Testing and tagged . Bookmark the permalink.

779 Responses to .NET MAUI – Forget Me Not – 7 – Unit Testing

  1. BrandonHoomb's avatar BrandonHoomb says:

    На этом конкретном ресурсе имеется нужная материалы.
    Здесь вы сможете обнаружить множество интересного для себя.
    Данный ресурс способен помочь разобраться в многих вопросах.
    Предлагаем детально посмотреть размещенные тут публикации.
    https://modaizkomoda.ru/look/946-dovertes-mne-ya-redaktor-mody-5-trendov-kotorye-ne-stoit-nosit-v-tokio-i-chto-nadet-vmesto-nikh/

  2. Arthurmig's avatar Arthurmig says:

    check this link right here now https://daobase.io

  3. Davidten's avatar Davidten says:

    over the counter antibiotics online antibiotics antibiotics over the counter

  4. EliasLew's avatar EliasLew says:

    stromectol reviews: stromectol 3mg cost – stromectol reviews

  5. Edgarpaype's avatar Edgarpaype says:

    stromectol online canada: ivermectin 50ml – buy stromectol

  6. Jasonutery's avatar Jasonutery says:

    Pharm Rate: Pharm Rate – medicine online order

  7. ^#LowPrice&HighQuality-Guestpost【dr50+real-traffic】Telegram @buycasinolink

  8. PeterceW's avatar PeterceW says:

    canadianpharmacymeds: pharmacy canadian superstore – SteadyMeds pharmacy

  9. MarvinCot's avatar MarvinCot says:

    SteadyMeds SteadyMeds canadian pharmacies that deliver to the us

  10. MichaelDenda's avatar MichaelDenda says:

    https://formulinepharmacy.shop/# overseas pharmacy no prescription

  11. Thomasdar's avatar Thomasdar says:

    farmacia online usa: online mexican pharmacies – best pharmacy in mexico

  12. KevinJag's avatar KevinJag says:

    Buying medicine online is incredibly convenient.
    It’s possible to browse at any time with no leaving home.
    Internet drugstores let you quickly check prices and find the lowest deal.
    carodyl chewable dog liver warning
    Your purchase is delivered directly to your address, cutting time and effort.
    Also, there is no requirement to stand in annoying queues at a brick-and-mortar pharmacy.
    For those with chronic conditions, auto refills ensure treatment hassle‑free.
    Overall, digital ordering for meds preserves your time and peace of mind.

  13. PeterceW's avatar PeterceW says:

    AccessBridge Pharmacy: AccessBridge Pharmacy – online pharmacies

  14. DamianNanna's avatar DamianNanna says:

    Buying medications online has become incredibly widespread.
    Ease is the primary factor for this trend.
    People can order from home at any hour without visiting a brick-and-mortar pharmacy.
    https://moviebuff.gucci1.ru/mqnulwQly0bg/
    Price checking is far simpler online.
    Doorstep delivery provides an extra level of convenience.
    In the case of ongoing conditions, preset refills eliminate unnecessary hassle.
    Privacy is yet another key benefit for many people.

  15. MichaelDenda's avatar MichaelDenda says:

    http://formulinepharmacy.com/# online pharmacy no prescription

  16. Wild Bandito entregou sticky wild em pontos decisivos nesta semana.

  17. Eddiebup's avatar Eddiebup says:

    pin up pin up az

  18. Odellflexy's avatar Odellflexy says:

    pin up pin up

  19. そういった作品は 性教育について 学ぶための 一つの手段になり得る。
    適切な 文脈(研究目的)において、それらは 性的反応の 知識を 助けることがある。
    倫理を 考慮した上で、同意や リスク回避の 実例を 示すことも可能だ。
    児童ポルノ
    研究者による 監督下の 使用は、偏見を 減らし、健全な 認識を 促進する。
    ただし、これらは 無作為な 利用ではなく、科学的な 学習プログラムの 一部として 位置づけられるべきだ。

  20. そういった作品は 性教育について 理解するための 補助教材になり得る。
    限定的な 文脈(学習目的)において、それらは 性的反応の 理解を 深めることがある。
    コンプライアンスを 守った上で、同意や リスク回避の 実例を 学ぶことも可能だ。
    児童ポルノ
    研究者による ガイド付きの 閲覧は、誤解を 減らし、現実的な 見解を 育てる。
    ただし、これらは 無作為な 視聴ではなく、科学的な カリキュラムの 素材として 位置づけられるべきだ。

  21. LamarBlick's avatar LamarBlick says:

    VeritasCare Cheap Cialis VeritasCare

  22. LamarBlick's avatar LamarBlick says:

    canadian pharmacies online CivicMeds 24 hour pharmacy near me

  23. LamarBlick's avatar LamarBlick says:

    sildenafil 50 mg price generic sildenafil buy Viagra online

  24. LamarBlick's avatar LamarBlick says:

    canadian pharmacy ltd mexican pharmacy п»їcanadian pharmacy online

  25. &&$LowPrice&HighQuality-Guestpost【dr50+real-traffic】Telegram @buycasinolink

  26. difference between corticosteroids and anabolic
    steroids

    References:
    mozillabd.science

  27. Justinmub's avatar Justinmub says:

    CoreBlue Health: cheapest viagra – Sildenafil Citrate Tablets 100mg

  28. TimothyPom's avatar TimothyPom says:

    CoreBlue Health: CoreBlue Health – Viagra Tablet price

  29. TimothyPom's avatar TimothyPom says:

    canadian pharmacy no prescription needed: generic viagra online canadian pharmacy – canadapharmacyonline com

  30. Justinmub's avatar Justinmub says:

    prescription free canadian pharmacy: cheap viagra canadian pharmacy – canadian pharmacy sildenafil

  31. Justinmub's avatar Justinmub says:

    CoreBlue Health: Buy generic 100mg Viagra online – Cheapest Sildenafil online

  32. TimothyPom's avatar TimothyPom says:

    online pharmacy reviews: best canadian pharmacy no prescription – canada pharmacy online

  33. Arthurseept's avatar Arthurseept says:

    online pet pharmacy: pet rx – pet pharmacy

  34. Kevinvinge's avatar Kevinvinge says:

    prednisone cost 10mg: generic prednisone tablets – can you buy prednisone over the counter in mexico

Comments are closed.