• Stars
    star
    195
  • Rank 199,430 (Top 4 %)
  • Language
    C#
  • License
    MIT License
  • Created almost 8 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Library for running Xamarin.Forms inside of unit tests

Xamarin.Forms.Mocks

Library for running Xamarin.Forms inside of unit tests

NuGet Windows / AppVeyor OS X / Travis-CI
NuGet AppVeyor Travis CI

If you've ever written any complicated logic inside a Xamarin.Forms View, you quickly realize that this code can't be unit tested easily. Your colleagues will tell you to MVVM all the things, but you cannot get around interacting with Xamarin.Forms itself. Things like navigation, animations, custom markup extensions, etc. can become an untested mess.

If you are determined to try it, you will probably do something like this and then give up: FAIL

You can now install this package from NuGet and get past this issue:

[SetUp]
public void SetUp()
{
    Xamarin.Forms.Mocks.MockForms.Init();
}

You can even do things in unit tests like load XAML dynamically:

using Xamarin.Forms.Xaml;
//...
[Test]
public void LoadFromXaml()
{
    var label = new Label();
    label.LoadFromXaml("<Label Text=\"Woot\" />");
    Assert.AreEqual("Woot", label.Text);
}

You can unit test navigation:

[Test]
public async Task Push()
{
    var root = new ContentPage();
    var page = new ContentPage();
    await root.Navigation.PushAsync(page);
    Assert.AreEqual(root.Navigation.NavigationStack.Last(), page);
}

You can unit test animations:

[Test]
public async Task FadeTo()
{
    var view = new BoxView();
    await view.FadeTo(0);
    Assert.AreEqual(0, view.Opacity);
}

You can even unit test your markup extensions:

public class TerribleExtension : IMarkupExtension<string>
{
    public string ProvideValue(IServiceProvider serviceProvider)
    {
        return "2016";
    }

    object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
    {
        return ProvideValue(serviceProvider);
    }
}

[Test]
public void MarkupExtension()
{
    var label = new Label();
    label.LoadFromXaml("<Label xmlns:f=\"clr-namespace:Xamarin.Forms.Mocks.Tests;assembly=Xamarin.Forms.Mocks.Tests\" Text=\"{f:Terrible}\" />");
    Assert.AreEqual("2016", label.Text); //amirite?
}

You can unit test persistence of Application properties:

[Test]
public async Task SaveAndLoad()
{
    var app = new App();
    app.Properties["Chuck"] = "Norris";
    await app.SavePropertiesAsync();

    app = new App();
    Assert.AreEqual("Norris", app.Properties["Chuck"]);
}

You can assert Device.OpenUri was called properly:

[Test]
public void OpenUri()
{
    var expected = new Uri("https://www.google.com");
    var actual = default(Uri);

    MockForms.OpenUriAction = u => actual = u;    
    Device.OpenUri(expected);
    Assert.AreEqual(expected, actual);
}

You can use Device.StartTimer as you would expect:

[Test]
public async Task StartTimer()
{
    var source = new TaskCompletionSource<bool>();
    Device.StartTimer(TimeSpan.FromMilliseconds(1), () =>
    {
        source.SetResult(true);
        return false;
    });

    Assert.IsTrue(await source.Task);
}

To test things using Application.Current or its resources:

[SetUp]
public void SetUp()
{
    MockForms.Init();

    //This is your App.xaml and App.xaml.cs, which can have resources, etc.
    Application.Current = new App();
}

[TearDown]
public void TearDown()
{
    Application.Current = null;
}

How does it work?

The main issue with trying to call Xamarin.Forms.Init() yourself for unit testing is that all kinds of interfaces and classes are marked internal. I get around this by conforming to [assembly: InternalsVisibleTo] which is declared for the purposes of unit testing Xamarin.Forms itself.

I merely named the output assembly Xamarin.Forms.Core.UnitTests.dll, and the MockForms class is able to call internal stuff all it wants. Just remember marking something internal does not mean someone tricky can't call it if they are determined enough.

I patterned after unit tests in Xamarin.Forms itself to figure out how to most easily mock everything.

Notes

Device.BeginInvokeOnMainThread is currently just synchronous. This may not be desired, but is the quickest plan for now.

All animations will just complete immediately. Just await them and use async unit tests.

I tested everything with NUnit, but nothing is tied specifically to it. Things should work find if you want to use a different unit testing library.

Xamarin.Forms versions

Make sure to choose the appropriate version of this package for the version of Xamarin.Forms you are using:

Xamarin.Forms Xamarin.Forms.Mocks
Any Newer Try latest & file issues, thanks!
4.7.0.x 4.7.0.x
4.6.0.x 4.6.0.x
3.5.x-4.5.x 3.5.0.x
3.0.0.x 3.0.0.x
2.5.0.x 2.5.0.x
2.4.0.x 2.4.0.x
2.3.5.x-pre 2.3.5.x-pre6
2.3.4.x 2.3.4.x
2.3.3.x 2.3.3.1
2.3.0-2.3.2 0.1.0.4
Older Unsupported

As another option, you can include the source code for this project along with your unit tests. This allows you to target any version of Xamarin.Forms desired assuming there are no code changes.

Wish List

  • I am not happy with Device.BeginInvokeOnMainThread being synchronous.
  • There are certainly other Xamarin.Forms internals not implemented. Let me know if there is something missing you need.
  • I back-dated this lib to support Xamarin.Forms 2.3.x, although it may be able to go back further. It is hard to know how often the forms team changed some of these internal interfaces.

More Repositories

1

dotnes

.NET for the NES game console
C#
617
star
2

spice

Spice 🌶, a spicy cross-platform UI framework!
C#
226
star
3

glidex

glidex.forms is a library using Glide for faster Xamarin.Forms images on Android. Find out more about Glide at https://github.com/bumptech/glide
C#
193
star
4

Xamarin.Android.Lite

Prototype/proof of concept of a "lite" Xamarin.Android that only supports Xamarin.Forms
C#
124
star
5

boots

boots is a .NET global tool for "bootstrapping" vsix & pkg files. Just "boots https://url/to/your/package"!
C#
86
star
6

Android-NativeAOT

A .NET 8, NativeAOT example on Android
C#
66
star
7

maui-profiling

Repository for building MAUI apps over time. So we can install & profile them.
C#
57
star
8

XPlatUtils

A set of helpers for cross platform apps. Right now has a ServiceContainer and Messenger implementation.
C#
37
star
9

memory-analyzers

C# code analyzers for finding memory leaks
C#
35
star
10

Mono.Profiler.Android

Support for the Mono profiler in .NET 6 Android applications
Shell
33
star
11

inclusive-code-reviews-browser

A chrome web extension for improving code reviews on Github or Azure DevOps
JavaScript
32
star
12

Xamarin.InAppPurchasing

Sample project for secure in-app purchases with Xamarin for iOS and Google Play
C#
27
star
13

XamChat

Simple chat application for iOS and Android
C#
26
star
14

UnityBuild

Example project showing automated builds with Unity3D
C#
24
star
15

lols

Performance test: LOLs per second
C#
24
star
16

HelloGlide

A simple sample using glidex.forms
C#
15
star
17

inclusive-code-reviews-ml

Machine learning for code reviews!
C#
14
star
18

Xamarin.SSLPinning

Test project to setup SSL pinning with Xamarin.iOS
C#
14
star
19

Xamarin.Forms.Benchmarks

Using BenchmarkDotNet to write some benchmarks for Xamarin.Forms concepts.
C#
11
star
20

measure-startup

C# console app to launch a process, wait for stdout, report a time
C#
8
star
21

MemoryLeaksOniOS

Testing memory leaks on iOS
C#
6
star
22

maui-scrolling-performance

Test repository for measuring scrolling performance of .NET MAUI apps on Android
C#
5
star
23

maui-workload

Prototype of a dotnet/maui "workload"
PowerShell
3
star
24

wpf-memory-leaks

Unit tests using WPF, to discover if/how it avoids memory leaks
C#
3
star
25

android-profiled-aot

This is a repo for recording .NET 6 AOT profiles.
C#
3
star
26

MyPal

A .NET MAUI sample application that uses omni-input LLMs to create "My Pal", a friendly koala that insults you based on a selfie!
C#
3
star
27

MonoGameSaveImage

Example of using Texture2D.SaveAsPng and Texture2D.SaveAsPng
C#
2
star
28

Benchmarks

Group of C# benchmarks for testing purposes
C#
2
star
29

baseline-profiles

For recording baseline profiles, see: https://developer.android.com/topic/performance/baselineprofiles
Java
2
star
30

CustomResourceDesigner

Example of making a "slimmer" Resource.designer.cs
C#
2
star
31

BenchmarkDotNet-Android

BenchmarkDotNet projects for comparing .NET 6 to Xamarin.Android
C#
2
star
32

DeleteBinObjBug

Reproducing DeleteBinObj and/or FastDev bug
Shell
2
star
33

Live.Forms.iOS

Xamarin.Forms live XAML reloading (iOS only)
C#
2
star
34

twitch-embeddinator

Demo project taking a Xamarin.Forms app and running it with Embeddinator-4000 in Android Studio
Java
2
star
35

maui-workload-pinning

This is an example of installing .NET MAUI Preview 7 and using RC1 packs
C#
2
star
36

XamarinAndroidBuildTimes

Quick repo I'll use to profile build times on different Xamarin.Android projects
PowerShell
2
star
37

Xamarin.Forms.Performance

Repo for testing performance in Xamarin.Forms on Android
C#
2
star
38

dotnet-using-task

Testing MSBuild <UsingTask/>
C#
2
star
39

Xamarin.Firebase.Messaging.Repro

Xamarin.Firebase.Messaging.Repro
C#
1
star
40

net6-finalizer-repro

Repro for: https://github.com/xamarin/xamarin-android/pull/6363#issuecomment-937379007
C#
1
star
41

Simulations

Levi's simulations
C#
1
star
42

class-lib-pack-r2r

Include ReadyToRun compiled assemblies in a NuGet/class library.
C#
1
star
43

GetRich

A mobile app that will basically make you rich if you submit it to the app store
C#
1
star
44

Embeddinator-MonoGame

Testing running MonoGame through Embeddinator
1
star
45

IntuneRepro

Trying to repro: https://github.com/msintuneappsdk/intune-app-sdk-xamarin/issues/5
C#
1
star
46

MSBuildIncrementalClean

This is a quick sample to figure out some nuances with MSBuild
PowerShell
1
star
47

MicrosoftExtensionsRepro

Trying to repro startup performance issue on Android
C#
1
star
48

gitinfotest

This is a repro for an MSBuild issue.
C#
1
star
49

maui-view-performance

Repo for measuring .NET MAUI views & page navigation
C#
1
star
50

inclusive-code-reviews-demo

Source code for my presentation "Using ML.NET and LLMs in C#"
C#
1
star