Unit Testing Application Layer w .NET – Mockowanie zależności z Moq
Testowanie Application Layer w .NET to moment, w którym wielu programistów zaczyna improwizować. Klasy mają zależności, pojawiają się repository, serwisy, pliki… a testy nagle przestają być unit. W tym artykule pokażę Ci jak testować Application Layer poprawnie, używając mockowania z Moq, na realnym przykładzie GameService. Bez teorii dla teorii. Z kodem, który działa i skaluje się w projektach enterprise.

Czym jest Application Layer w Clean Architecture?
Application Layer to orkiestrator przypadków użycia. Nie zawiera logiki biznesowej (to rola Core), ani dostępu do danych (Infrastructure). Jego zadaniem jest:
- koordynowanie współpracy komponentów
- walidacja wejścia i flow aplikacji
- delegowanie pracy do odpowiednich serwisów
👉 To właśnie dlatego Application Layer zawsze ma zależności – i właśnie dlatego jego testowanie jest trudniejsze.
Zobacz też: Czym jest Clean Architecture w .NET

Dlaczego bez mocków to nie są unit testy?
Jeśli w teście Application Layer:
- używasz prawdziwego
Repository - czytasz pliki z dysku
- uruchamiasz prawdziwy
BattleService
…to nie piszesz unit testów, tylko testy integracyjne.
Problemy testów bez mocków:
- ❌ wolne (I/O, Thread.Sleep)
- ❌ niestabilne (pliki, dane testowe)
- ❌ testują kilka klas naraz
- ❌ bug w innej warstwie psuje test
Rozwiązanie? Mockowanie zależności.

Czym jest mock i po co go używamy?
Mock to kontrolowana, fake’owa implementacja interfejsu, której zachowanie definiujesz w teście.
Dzięki mockom możesz:
- ustalić co metoda ma zwrócić (
Setup) - sprawdzić czy została wywołana (
Verify) - zasymulować błędy (
Throws)
W .NET najczęściej używamy do tego biblioteki Moq.
Przykład: GameService w Application Layer
GameService zależy od:
IPostacRepositoryIBattleService
public class GameService : IGameService
{
private readonly IPostacRepository _postacRepository;
private readonly IBattleService _battleService;
private List<Postac> _postacie = new();
public IReadOnlyList<Postac> Postacie => _postacie.AsReadOnly();
public GameService(IPostacRepository postacRepository, IBattleService battleService)
{
_postacRepository = postacRepository;
_battleService = battleService;
}
...
}
👉 Naszym celem jest przetestować GameService w izolacji, bez prawdziwych implementacji.
Setup testów – fundament Application Layer Testing
Zanim napiszemy pierwszy test, robimy trzy rzeczy:
- mock każdej zależności
- brak
newdla prawdziwych klas - jedna testowana klasa
public class GameServiceTests
{
private readonly Mock<IPostacRepository> _mockRepository;
private readonly Mock<IBattleService> _mockBattleService;
private readonly GameService _gameService;
public GameServiceTests()
{
_mockRepository = new Mock<IPostacRepository>();
_mockBattleService = new Mock<IBattleService>();
_gameService = new GameService(_mockRepository.Object, _mockBattleService.Object);
}
...
}
To jest święta trójca unit testów Application Layer.
Test 1: delegacja do Repository (happy path)
[Fact]
public void PobierzPostacie_WithValidPath_ShouldLoadCharacters()
{
// Arrange
var expectedCharacters = new List<Postac>
{
new Wojownik("Test Warrior"),
new Mag("Test Mage")
};
var testFilePath = Path.GetTempFileName();
_mockRepository.Setup(r => r.PobierzPostacie(testFilePath))
.Returns(expectedCharacters);
// Act
_gameService.PobierzPostacie(testFilePath);
// Assert
_gameService.Postacie.Should().HaveCount(2);
_gameService.Postacie.Should().BeEquivalentTo(expectedCharacters);
_mockRepository.Verify(r => r.PobierzPostacie(testFilePath), Times.Once);
// Cleanup
File.Delete(testFilePath);
}
✔ test delegacji ✔ test stanu ✔ pełna izolacja

Verify – najważniejsze narzędzie w Application Layer
Verify() pozwala sprawdzić:
- czy metoda została wywołana
- ile razy (
Times.Once,Times.Never) - z jakimi parametrami (
It.Is<T>)
To są testy kontraktu i architektury, nie tylko funkcjonalności.

Najczęstsze błędy przy testowaniu Application Layer
Checklist:
- ❌ testowanie implementacji zamiast zachowania
- ❌ brak mocków
- ❌ testowanie kilku klas naraz
- ❌ brak
Verify - ❌ logika biznesowa w Application Layer
Jeśli test trudno napisać → design jest problemem.
Podsumowanie
Testowanie Application Layer w .NET:
- wymaga mockowania zależności
- wymusza dobry design
- chroni architekturę
- daje szybkie i stabilne testy
To nie jest „zaawansowane testowanie”. To podstawa pracy zawodowego .NET developera.
👉 Zostaw komentarz – z czym masz największy problem przy testach?
👉 Sprawdź też: Unit Testing Core Layer w .NET

