maui-accessibility
Guide for making .NET MAUI apps accessible — screen reader support via SemanticProperties, heading levels, AutomationProperties…
xUnit testing guidance for .NET MAUI apps — ViewModel testing, mocking MAUI services, test project setup, code coverage, and on-device test runners. USE FOR: "unit test MAUI", "xUnit test", "ViewModel testing", "mock MAUI services", "test project setup", "code coverage",
$ npx -y skills add davidortinau/maui-skills --skill maui-unit-testing --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/maui-unit-testingContext preview
The summary Claude sees to decide when to auto-load this skill.
xUnit testing guidance for .NET MAUI apps — ViewModel testing, mocking MAUI services, test project setup, code coverage, and on-device test runners. USE FOR: "unit test MAUI", "xUnit test", "ViewModel testing", "mock MAUI services", "test project setup", "code coverage",
name: maui-unit-testing description: > xUnit testing guidance for .NET MAUI apps — ViewModel testing, mocking MAUI services, test project setup, code coverage, and on-device test runners. USE FOR: "unit test MAUI", "xUnit test", "ViewModel testing", "mock MAUI services", "test project setup", "code coverage", "on-device test runner", "test MAUI app", "IServiceProvider mock", "Moq MAUI". DO NOT USE FOR: UI automation testing (use appium-automation), performance profiling (use maui-performance), or dependency injection setup (use maui-dependency-injection).
For project templates, xUnit examples, ViewModel test patterns, and CLI commands, see `references/unit-testing-api.md`.
<!-- ❌ xUnit can't run on platform-specific TFMs --> <TargetFramework>net9.0-ios</TargetFramework> <!-- ✅ Use plain .NET TFM for desktop test host --> <TargetFrameworks>net9.0;net10.0</TargetFrameworks>
If your test project references the app project, the app tries to build as `Exe` for the test TFM — this fails. Add a conditional `OutputType`:
<!-- ❌ App .csproj without conditional — breaks test builds --> <OutputType>Exe</OutputType> <!-- ✅ Library for test TFM, Exe for platform TFMs --> <PropertyGroup Condition="'$(TargetFramework)' == 'net9.0'"> <OutputType>Library</OutputType> </PropertyGroup> <PropertyGroup Condition="'$(TargetFramework)' != 'net9.0'"> <OutputType>Exe</OutputType> </PropertyGroup>
ViewModels that directly call static MAUI APIs are untestable:
// ❌ Untestable — Shell.Current requires a running MAUI app
public async Task GoToDetail(int id)
=> await Shell.Current.GoToAsync($"detail?id={id}");
// ✅ Inject an interface — fully testable
public class MyViewModel(INavigationService nav)
{
public async Task GoToDetail(int id)
=> await nav.GoToAsync($"detail?id={id}");
}Static APIs to wrap behind interfaces:
// ❌ Testing the binding — fragile, needs a running UI
Assert.Equal("Hello", label.Text);
// ✅ Testing the ViewModel — fast, no platform dependency
Assert.Equal("Hello", viewModel.Title);
Assert.True(viewModel.SaveCommand.CanExecute(null));| MAUI Service | Mock Strategy | |-------------|---------------| | `ISecureStorage` | `Mock<ISecureStorage>` — stub `GetAsync`/`SetAsync` | | `IPreferences` | `Mock<IPreferences>` — stub `Get`/`Set`/`Remove` | | `IConnectivity` | `Mock<IConnectivity>` — return `NetworkAccess` | | `IGeolocation` | `Mock<IGeolocation>` — return fixed `Location` | | `IFilePicker` | `Mock<IFilePicker>` — return `FileResult` | | `IMediaPicker` | `Mock<IMediaPicker>` — return `FileResult` | | Shell navigation | Abstract behind `INavigationService` | | `IDispatcher` | Stub `Dispatch` to invoke action synchronously |
Define service interfaces so ViewModels have zero MAUI platform dependencies:
// ✅ These make your entire ViewModel layer testable
public interface INavigationService
{
Task GoToAsync(string route);
Task GoBackAsync();
}
public interface IDialogService
{
Task<bool> ConfirmAsync(string title, string message);
}Register implementations in `MauiProgram.cs`; inject interfaces into ViewModels.
A collection of 41 skills for .NET MAUI development, UI/UX design reasoning, and Xamarin migration, designed for use with GitHub Copilot CLI and Claude Code.
Guide for making .NET MAUI apps accessible — screen reader support via SemanticProperties, heading levels, AutomationProperties…
.NET MAUI view animations, custom animations, easing functions, rotation, scale, translation, and fade effects. USE FOR: "animate…
.NET MAUI app icon configuration, splash screen setup, SVG to PNG conversion at build time, composed/adaptive icons, and…
.NET MAUI app lifecycle guidance covering the four app states (not running, running, deactivated, stopped), cross-platform Window…
Guide for .NET MAUI apps consuming .NET Aspire-hosted backend services. Covers AppHost configuration, service discovery for…
Add authentication to .NET MAUI apps. Covers WebAuthenticator for generic OAuth 2.0 / social login, and MSAL.NET for Microsoft…