Log In

Don't have an account? Sign up now

Lost Password?

Sign Up

Prev Next

Module 16: Testing in .NET

Testing is often what separates a hobbyist from a professional engineer. In an enterprise environment, “it works on my machine” isn’t enough; you need an automated suite of tests to prove that a new change doesn’t break existing features (this is called Regression Testing).


1. The Testing Pyramid

To build a stable system, you should follow the Testing Pyramid strategy:

  • Unit Tests (Base): Hundreds of fast tests for individual methods.
  • Integration Tests (Middle): Fewer tests that check if your code works with the Database or APIs.
  • E2E/UI Tests (Top): Very few tests that simulate a user clicking buttons in a browser.

2. Unit Testing Fundamentals

A Unit Test focuses on the smallest possible “unit” of code (usually a single method) in isolation.

  • The AAA Pattern: The industry standard for writing a test:
    1. Arrange: Set up the objects and data needed.
    2. Act: Call the method you are testing.
    3. Assert: Verify that the result is what you expected.
  • Isolation: A unit test should never talk to a real database, a real file system, or the internet.

3. xUnit vs. NUnit

These are the two most popular testing frameworks in the .NET ecosystem.

  • xUnit: The modern choice, used by the .NET team themselves. It uses the [Fact] attribute for normal tests and [Theory] for data-driven tests.
  • NUnit: An older, classic framework that uses [Test] and [TestCase]. It is still very common in legacy enterprise projects.

4. Moq & Mocking

Since unit tests must be isolated, how do you test a UserService that requires a database? You Mock it.

  • Mocking: Creating a “fake” version of an interface that returns pre-defined data.
  • Moq: The most popular library for this in .NET.
    • Real: Goes to the database (slow, unreliable for tests).
    • Mock: An object that says, “If anyone asks for User #1, just return this C# object I made in memory.”

5. Integration Testing

Integration tests verify that different parts of your application work together correctly.

  • The Scope: They test your code against a real database (often an “In-Memory” database or a temporary Docker container) or a real file system.
  • WebApplicationFactory: A powerful .NET tool that allows you to spin up your entire API in memory during a test to see if the Controllers, Middleware, and Database all play nice together.

6. Test-Driven Development (TDD)

TDD is a workflow where you write the test before the code.

  1. Red: Write a test for a feature that doesn’t exist yet. Run it; it fails.
  2. Green: Write just enough code to make the test pass.
  3. Refactor: Clean up the code while ensuring the test stays green.

Why use TDD? It forces you to think about the “Requirements” and “Interface” of your code before you get bogged down in the implementation.


7. Real-World Example (xUnit + Moq)

C#

[Fact]
public void CalculateDiscount_ShouldReturnHalfPrice_WhenUserIsStudent() {
    // Arrange
    var mockSvc = new Mock<IUserTypeService>();
    mockSvc.Setup(s => s.GetStatus(1)).Returns("Student");
    
    var calculator = new DiscountCalculator(mockSvc.Object);

    // Act
    var result = calculator.GetTotal(100, 1); // $100 price for User #1

    // Assert
    Assert.Equal(50, result);
}

Leave a Comment

    🚀 Join Common Jobs Pro — Referrals & Profile Visibility Join Now ×
    🔥