Mert Özen Further With Every Line

Blog

Mert Özen's blog posts on software development, backend, frontend, and DevOps.

Series
.NET Core Web API 36 Angular 31 JavaScript Basics 19 JavaScript Intermediate 18 JavaScript Advanced 16 TypeScript Basics 14 TypeScript Intermediate 14 TypeScript Advanced 12 Entity Framework Core 28 Dapper 16 Git & GitHub 29 Web Security (OWASP Top 10) 21 LLM Fundamentals 20 C# Fundamentals 20 Object-Oriented Programming in C# 16 C# Collections and Generics 11 LINQ 17 Asynchronous Programming in C# 17 Advanced C# 14 C# Versions 6 Solution Patterns 22 SOLID and Design Principles 12 Clean Code 13 Design Patterns 23 UML and Modeling 18 Introduction to Software Architecture 9 Clean, Onion and Hexagonal Architecture 8 Vertical Slice Architecture 6 Domain-Driven Design 12 CQRS and Event Sourcing 10 Messaging and Event-Driven Architecture 9 Modular Monolith 2 Microservices 10 UI Architecture Patterns 9 Architecture Decisions 7 System Design 15 Distributed Systems Fundamentals 11 Background Jobs and Scheduled Jobs 11 Working with Message Queues 14 Logging in .NET 10 Caching 10 Real-time Applications 9 ASP.NET Core MVC and Razor Pages 13 CI/CD Fundamentals 8 GitHub Actions 16 Jenkins 12 Web Servers and Hosting 12 Deployment Strategies 9 Kubernetes 19 Authentication and Authorization 18 ASP.NET Core Security 8 Frontend Security 9 API Security (OWASP API Top 10) 11 AI with .NET 14 RAG 13 AI Agents and MCP 14 Test Strategy 4 Unit Testing 13 SDLC (Software Development Life Cycle) 6 Agile Mindset 6 Scrum 11 Kanban 7 Introduction to Product Management 9 SEO Fundamentals 7 Technical SEO 12 GEO (Generative Engine Optimization) 7 Algorithms and Data Structures 22 Debugging and Problem Solving 13
13 posts found #dotnet
What Is the "Unit" in Unit Testing? Classical vs London School and the Four Pillars of a Good Test
Testing & Quality PART 01

What Is the "Unit" in Unit Testing? Classical vs London School and the Four Pillars of a Good Test

A unit is a behavior, not a method or a class; the classical school, which uses test doubles only at the system boundary, produces tests that resist refactoring better than the London school, which mocks every collaborator. Solitary vs sociable tests, Khorikov's four pillars of a good test, and real output showing how a behavior-preserving change breaks a mocked test.

8 Nov 2026 11 min 3
A Test Project with xUnit v3: Microsoft Testing Platform, dotnet test and First Tests
Testing & Quality PART 02

A Test Project with xUnit v3: Microsoft Testing Platform, dotnet test and First Tests

An xUnit.net v3 test project is an executable and, since 4.0, runs on Microsoft Testing Platform v2 by default; once global.json sets the test runner on the .NET 10 SDK, dotnet test rejects VSTest projects. The xunit3 template, the package chain, dotnet test vs dotnet run, Assert.Throws/ThrowsAsync, TestContext.Current.CancellationToken and xUnit1051, filters, TRX reports and exit code 8.

8 Nov 2026 11 min 5
Anatomy of a Good Unit Test: AAA, Naming, One Behavior and Readable Assertions
Testing & Quality PART 03

Anatomy of a Good Unit Test: AAA, Naming, One Behavior and Readable Assertions

A good unit test runs one behavior through a single Act, contains no branching, and when it turns red its name and failure message explain the problem without opening the code. The limits of AAA, Method_Scenario_Expected vs plain-sentence naming, Assert.Multiple, and Shouldly, AwesomeAssertions and FluentAssertions 8's Xceed license, with real failure messages.

8 Nov 2026 10 min 5
Data-Driven Tests in xUnit v3: Theory, MemberData, TheoryData, TheoryDataRow and MatrixTheoryData
Testing & Quality PART 04

Data-Driven Tests in xUnit v3: Theory, MemberData, TheoryData, TheoryDataRow and MatrixTheoryData

In data-driven tests, which rows you pick matters more than how many: boundary values and equivalence partitioning caught Math.Round's banker's rounding with two rows. In xUnit v3: InlineData, MemberData and type-safe TheoryData, TheoryDataRow with per-row display name, label, trait and skip, MatrixTheoryData, dynamic skip, Explicit tests, and how non-serializable data affects Test Explorer.

8 Nov 2026 9 min 5
The xUnit Test Lifecycle: Constructors, IAsyncLifetime, Fixtures and Full Parallelism in 4.0
Testing & Quality PART 05

The xUnit Test Lifecycle: Constructors, IAsyncLifetime, Fixtures and Full Parallelism in 4.0

xUnit creates a new instance of the test class for every test; expensive, read-only setup is done once in a class, collection or assembly fixture. In 4.0, ParallelMode.All cut an 8-test example from 1.06 to 0.55 seconds, but two tests sharing a static fake failed in 16 of 20 runs. IAsyncLifetime, opt-out levels, ITestOutputHelper and TestContext attachments.

8 Nov 2026 10 min 5
Test Doubles: The Difference Between Dummy, Stub, Spy, Mock and Fake
Testing & Quality PART 06

Test Doubles: The Difference Between Dummy, Stub, Spy, Mock and Fake

A test double's kind is decided by its role in the test, not by its library: a dummy fills a slot, a stub supplies data, spies and mocks verify outgoing calls, and a fake is a working shortcut. The Meszaros taxonomy, Fowler's state vs behavior verification, why asserting on stubs hurts, how a fake that does not copy records hid a missing SaveAsync, and FakeTimeProvider and FakeLogger.

8 Nov 2026 10 min 3
Mocking Libraries in Depth: NSubstitute, Moq and FakeItEasy
Testing & Quality PART 07

Mocking Libraries in Depth: NSubstitute, Moq and FakeItEasy

NSubstitute, Moq and FakeItEasy share the same Castle DynamicProxy engine, so they can only fake interfaces and virtual members, and the differences between them are mostly syntax and failure messages. The same payment scenarios in all three: argument matching and capture, sequential returns, async exceptions, call count and order, strict mode, the NS1000 analyzer warning and Moq's 2023 SponsorLink incident.

8 Nov 2026 11 min 5
When Not to Mock: Over-Mocking, Brittle Tests and "Don't Mock What You Don't Own"
Testing & Quality PART 08

When Not to Mock: Over-Mocking, Brittle Tests and "Don't Mock What You Don't Own"

Mocks belong only at the system boundary, for unmanaged dependencies observable from outside; domain objects and the application's own database are not mocked. A mocked exchange rate adapter kept tests green while production showed 100 EUR as 0 TRY; an HttpMessageHandler stub caught the bug on the first run. Output, state and communication test styles and the managed vs unmanaged distinction.

8 Nov 2026 9 min 4
Testable Design: Dependency Injection, Seams, Functional Core and Humble Object
Testing & Quality PART 09

Testable Design: Dependency Injection, Seams, Functional Core and Humble Object

What makes code testable is moving decisions into a pure core and leaving time, I/O and framework code in a thin shell; the decisions can then be tested without mocks. A discount test using DateTime.Now depended on the calendar and hid the Istanbul vs UTC gap. Kinds of seams, TimeProvider, functional core / imperative shell, Humble Object with BackgroundService, and characterization tests for legacy code.

8 Nov 2026 9 min 5
Keeping Test Code Clean: Test Data Builders, Object Mothers, AutoFixture and Bogus
Testing & Quality PART 10

Keeping Test Code Clean: Test Data Builders, Object Mothers, AutoFixture and Bogus

The rule for test data is simple: the value a test relies on is written explicitly in the test, and the rest is left to meaningful defaults or anonymous data. A shipping test written with unseeded Bogus data failed in 6 of 30 runs. Test Data Builders, the growth problem of Object Mothers, AutoFixture and AutoData, AutoNSubstitute's NU1608 warning with NSubstitute 6, seeded Bogus, and the DRY vs DAMP balance in test code.

8 Nov 2026 8 min 4
Hard Cases in Unit Testing: Async Code, Time, Exceptions, Logging and Background Services
Testing & Quality PART 11

Hard Cases in Unit Testing: Async Code, Time, Exceptions, Logging and Background Services

With code tested through FakeTimeProvider, the rule is: start the operation, advance the clock, then await; a retry test that awaited first hit its 2-second timeout because the clock never moved. Verifying backoff as a pure function, the retry flow with a fake clock, exceptions by type and data, the critical log with FakeLogger, cancellation, and a BackgroundService consuming a Channel<T> with deterministic tests.

8 Nov 2026 8 min 4
Snapshot and Property-Based Testing: Extending Unit Tests with Verify and FsCheck
Testing & Quality PART 12

Snapshot and Property-Based Testing: Extending Unit Tests with Verify and FsCheck

Property-based testing tries a rule that holds for every input with random inputs, and snapshot testing approves a large output as a whole; both complement example tests. FsCheck found the negative total that three example tests missed on its first try and shrank it to a 0 EUR cart and a 1 EUR coupon; Verify caught a property rename as a contract change. Shrinking, custom arbitraries, scrubbers and Verify 33's maintenance fee check.

8 Nov 2026 10 min 4
Blog Map