Getting Started with Xamarin.Forms and Unit Testing with xUnit and Moq

Previous posts in this sequence on Getting Started with Xamarin.Forms:
Multi-Targeting in Visual Studio, SDK Versions, MvvmCross, Authenticating with ADAL
Refactoring MvvmCross and Services, Effects, Navigation with MvvmCross
Presentation Attributes in MvvmCross, Resources and Styles, Resource Dictionaries
Platform Specific Resources with OnPlatform, Device Customization using OnIdiom

When we kicked off this project we separated out the business logic from the user interface into Core and UI projects respectively. The main aim was to ensure clear separation of context and to allow for the business logic to be developed, and more importantly, tested, independently of the UI. In this post we’ll get started with unit testing our Core library using xUnit. I’ll also touch on using the mocking library, Moq, to make our testing lives easier.

To get started we’ll add another project to our solution, this time based on the xUnit Test Project (.NET Core) from the Add New Project dialog.

image

If we inspect what gets added we’ll see that it’s a regular single targeted project with references to xUnit and the Microsoft test library.

image

After creating the project, don’t forget to do the obligatory NuGet package update. If you open the UnitTest1 class you can right-click within the Test1 method and select Run Test(s).

image

When you execute tests within Visual Studio you can see the execution progress in the Output window. If it doesn’t automatically switch, you may need to select Tests for the “Show output from” dropdown.

image

Before we can write tests for our Core library, we need to add a reference to the Core library to the Testing library.

image

Now we’re ready to start creating our own tests (you can delete UnitTest1.cs since we won’t be needing it). Everyone has their own naming convention and structure for testing library. I tend to mirror the layout of the project I’m testing. So in this case I’ve created a ViewModels folder within the test project and have created a class MainViewModelTest class.

At this point I’m also going to add a reference to Moq (https://www.nuget.org/packages/Moq) which I’ll use as part of the test method

public class MainViewModelTest
{
     [Fact]
     public async Task AuthenticateTest()
     {
         var credentialsMock = new Mock<ICredentialService>();
         credentialsMock.Setup(x => x.Authenticate()).Returns(() => Task.FromResult(“SomeRandomAccessToken”));


        var mainViewModel = new MainViewModel(
             new Mock<IMvxLogProvider>().Object,
             new Mock<IMvxNavigationService>().Object,
             credentialsMock.Object);
         Assert.True(await mainViewModel.Authenticate());
     }
}

Here I’ve kept the AuthenticateTest method relatively straight forward – I created a mock instance of the ICredentialService which returns a predefined access token; this is then used along with two other mock objects when creating the MainViewModel instance. I then assert that calling the Authenticate returns true (i.e. because the Authenticate method on the ICredentialService instance returns a not-null access token).

Right-click within this test method to run the test returns a positive outcome in the Output window. You can also run and see the results of running test cases via the Test Explorer window.

image

And that’s it, you can now write as many test cases as you feel are necessary for your services, viewmodels and other Core classes.

Leave a comment