Pluralsight Notes – Effective C# Unit Testing for Enterprise Applications

Introduction

Pluralsight is a great online resource for Developer/Technology training courses.  I have recently begun working through a bunch of courses and I thought I would begin sharing my notes I take while viewing these courses.  Effective C# Unit Testing for Enterprise Applications by Rusty Divine, aims to improve the viewers unit testing knowledge through solid patterns and practices to follow and understanding what to avoid.

Learning The Basics of Effect Unit Tests

  • Prerequisites
    • Clean code
    • Testable design – Interfaces
    • Context-aware
    • Understanding of unit testing
  • 3 pillars of unit testing
    • Clear and simple
    • High value – testing essential code
    • Flexible – tests that don’t break when code is refactored

Creating Clear and Simple Tests That Emphasize Readability

  • Test naming conventions
  • Specific test scenarios
  • 3 Part Naming
    • Unit of work being tested (Title, main scenario being tested)
    • Initial condition (Scenario under test)
    • Expected Result
    • UserLogsIn_WithValidCreds_RedirectsToHome
    • UserLogsIn_WithBadPassword_ReturnsError
  • Test method resharper template
  • Directly targeting ctor or private methods could make refactoring difficult (unit tests should not have internal knowledge)
  • DAMP – descriptive and meaningful phrases
  • Arrange/Act/Assert
  • Fluent Assertions (.net library) (nuget)
  • Builder pattern to protect against new ctor dependencies
  • Integration test – call out to an external dependency
  • Test precision helps narrow down failure scope

Creating High Value tests That Cover Your Riskiest Code

  • Composition over inheritance
  • Difficult to substitue behavior with inheritance
  • Elements of Testable Code
    • Ask for what you need
    • Avoid “new”
    • Avoid mutable global state
    • Beware static methods
    • Add Seams
    • Composition over inheritance
  • SOLID
  • Risk driven testing (High Value Tests)
    • Complex logic
    • Workflows
    • Validations
    • Calculations
  • Value test – tests business logic – expect the correct value
  • State test – expect some system state change
  • Interaction test – checking if a method is called (too many is bad)
  • Datetime service – do not rely on the system time
  • How much testing – what is the context we are working with
    • Public api
    • LOB
  • Trivial tests lead to refactor friction

Creating Flexible Tests That Allow You to Refactor Your Code

  • Test unit of work Public API layer
  • Test unit of work at DAL
  • Integration tests should be separated from unit tests
  • Test unit of work – Testing how api is actually used
  • Test one interaction per test
  • Limit use of mocks
  • Test by scenario no by method

Bringing it Together with Guidelines, Checklists, and Resources

  • Code review guidelines
    • Common ground
    • Power of a checklist
    • Structure for improvement
  • Unit testing checklist
    • Test name describes the scenario
    • Contains Arrange, Act, Assert
    • Stays within on project layer
    • Is a state, value or interaction test
    • Fakes all dependencies
    • Mocks at most one dependency
    • Favors the public API
    • Asserts against one object
    • Favors builder over setup methods
  • Google testing blog (Suggested Articles)
    • Don’t overuse mocks
    • Testing State vs. Interactions
    • Prefer testing public APIs over implementation-Detail Classes
    • Test Behaviors not methods
    • Effective Testing
    • Measuring Coverage
  • Book: The Art of Unit Testing: with examples in C# 2nd Edition by Rot Osherove
  • http://ArtOfUnitTesting.com