📌 概要
MAUI プロジェクトのテストコードは「定型的で手書きが苦痛」ですよね。このスキルは xUnit + Moq を使用した ViewModel・Service・Repository のユニットテストを 自動生成 することで、テスト駆動開発(TDD)を実践しやすくします。
🤔 背景・なぜ必要か
従来のテスト作成の課題
// ❌ テストコードの定型部分が多い
public async Task GetHabits_WhenHabitsExist_ReturnsHabitList()
{
var habits = new List<Habit> { ... };
_mockRepository.Setup(r => r.GetAllAsync()).ReturnsAsync(habits);
var viewModel = new HabitListViewModel(_mockRepository.Object);
await viewModel.LoadHabitsAsync();
Assert.NotNull(viewModel.Habits);
_mockRepository.Verify(r => r.GetAllAsync(), Times.Once);
}
毎回、Arrange(準備)→ Act(実行)→ Assert(検証) の流れを書く必要があり、ビジネスロジックの仕様を考えるより「テストコードの書き方」に頭を使ってしまいます。
スキルの解決方法
- 自動生成: Copilot が「ViewModel のメソッド名」から必要なテストを判定
- 命名規則統一:
[メソッド]_[シナリオ]_[期待結果]で可読性維持 - テスト階層化: ViewModel → Service → Repository の順で優先度付け
💻 実装方法
ステップ1: テストプロジェクトフォルダ構成
HabitTracker.Tests/
├── Fixtures/
│ └── MockRepositoryFixture.cs
├── ViewModels/
│ └── HabitListViewModelTests.cs
├── Services/
│ └── HabitServiceTests.cs
└── Repositories/
└── HabitRepositoryTests.cs
ステップ2: ViewModel テスト自動生成
ViewModel HabitListViewModel に対して、以下をスキルに指示:
「HabitListViewModel の LoadHabitsAsync メソッドのユニットテストを xUnit + Moq で生成してください」
生成されたテスト例:
[Fact]
public async Task LoadHabitsAsync_WhenHabitsExist_PopulatesHabitList()
{
// Arrange
var habits = new List<Habit>
{
new Habit { Id = 1, Name = "Running", IsActive = true }
};
_mockRepository.Setup(r => r.GetAllAsync())
.ReturnsAsync(habits);
var viewModel = new HabitListViewModel(_mockRepository.Object);
// Act
await viewModel.LoadHabitsAsync();
// Assert
Assert.NotNull(viewModel.Habits);
Assert.Single(viewModel.Habits);
_mockRepository.Verify(r => r.GetAllAsync(), Times.Once);
}
[Fact]
public async Task AddHabitAsync_WhenNameEmpty_DoesNotAdd()
{
var viewModel = new HabitListViewModel(_mockRepository.Object);
viewModel.HabitName = string.Empty;
await viewModel.AddHabitAsync();
_mockRepository.Verify(r => r.AddAsync(It.IsAny<Habit>()), Times.Never);
}
ステップ3: テスト実行とカバレッジ測定
# テスト実行
dotnet test HabitTracker.Tests
# カバレッジ計測
dotnet test HabitTracker.Tests /p:CollectCoverage=true
⭐ ポイント
1. モック設定の統一性
- すべての Repository モックは
IHabitRepositoryを共通化 - Setup パターンは「GetAllAsync → ReturnsAsync」で統一
2. テスト優先度
ViewModel(最優先) ← 80% 以上のカバレッジ目標
↓
Service(中優先) ← 複雑なビジネスロジックがある場合
↓
Repository(参考) ← EF Core の動作はマイクロソフトが保証
3. よくあるミス
- ❌
Times.Onceを忘れて Verify しない - ❌ Async メソッドで
.Wait()を使う(デッドロック) - ❌ Mock の戻り値を
nullにする(NullReferenceException)
4. テスト命名規則の重要性
// ✅ 良い例
[Fact]
public async Task LoadHabitsAsync_WhenHabitsExist_PopulatesHabitList()
// ❌ 悪い例
[Fact]
public async Task TestLoadHabits()
✅ まとめ
ユニットテスト生成スキルは、TDD を実践するための「最初のハードル」を下げる ものです。テストコード自体ではなく「どのテストケースが必要か」に集中できます。
カバレッジ 80% 以上を目指して、安心して機能追加できるプロジェクト文化を作りましょう!

コメント