Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly...

67
Matthew Butt Unit Testing the Hard Stuff matthewbutt.com @bnathyuw

Transcript of Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly...

Page 1: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Matthew Butt

Unit Testing the Hard Stuffmatthewbutt.com @bnathyuw

Page 2: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

NB

There will be codeIt will be C#I will explain it

Page 3: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Axiom:

Unit Tests are Importantfeedback for delivering quality software

Page 4: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

SpeedControl

Precision

Page 5: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Observation:

Some projects have no Unit Tests

Page 6: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Why?

Page 7: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Why?not Designed for Test

few Techniquesfew Tools

not even many Workarounds

Page 8: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Unit Testingthe Easy Stuff

Page 9: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Designed for TestTools

Techniquesor at least Workarounds

Page 10: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

.NET Web API

Page 11: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

[Whiteboard]

Page 12: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Designed for Test

Directly ExecutableObject OrientedAbstractionsDI

Page 13: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Techniques

SOLID designMockingArchitecture Patterns

(MVC, ports & adapters, hexagonal…)

Page 14: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Tools

NUnit… test framework

NSubstitute…mocking framework

OWIN… in-memory host

Page 15: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Workarounds

Adaptersaround leaky abstractions

Mock Clockand other system dependencies

Page 16: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Speed Run locallyControl Test doubles

Precision Class levelClear purpose

Page 17: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Outside-in approach

Acceptance test outer loop

Unit test inner loop

Page 18: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Acceptance Test

In-Memory HostStub Externals

Page 19: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Controller Test

In-Memory HostTreat as adapter

Mock DependenciesTest interactions

Keep it thinNo domain logic

Page 20: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Domain Object Tests

State or Interaction?State: stubs

Interaction: mocks

Single ResponsibilityListen to your tests!

Page 21: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

External dependencies

AbstractionsInterfaces in Domain

Integration testsNo test if trivial

Clock

Page 22: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

namespace EasyStuff.Api.Domain {public interface IClock {

DateTime Now { get; }}

}

namespace EasyStuff.Api.Adapters {public class SystemClock : IClock {

public DateTime Now => DateTime.UtcNow;}

}

var knownDate = new DateTime(2001, 2, 3);var clock = Substitute.For<IClock>();clock.Now.Returns(knownDate);

Page 23: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Unit Testingthe Hard Stuff

Page 24: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Microsoft AzureData Lake Analytics

Page 25: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Financial TransactionsWeather Data

Page 26: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

AberporthLocation: 224100E 252100N, Lat 52.139 Lon -4.570, 133 metres amslEstimated data is marked with a * after the value.Missing data (more than 2 days missing in month) is marked by ---.Sunshine data taken from an automatic Kipp & Zonen sensor marked with a #, otherwise sunshine data taken from a Campbell Stokes recorder. yyyy mm tmax tmin af rain sun degC degC days mm hours 1970 1 7.5 3.1 7 97.5 40.2 1970 2 6.2 1.9 7 79.2 96.2 1970 3 6.6 2.0 8 76.1 101.2 1970 4 8.8 4.2 2 67.0 135.2 1970 5 14.5 8.5 0 28.1 148.9 1970 6 18.5 11.5 0 47.3 206.5 1970 7 16.6 11.3 0 57.4 150.3 1970 8 17.8 12.3 0 42.6 151.8 1970 9 16.8 11.5 0 49.4 120.4 1970 10 13.3 8.6 0 108.3 75.4 1970 11 10.8 6.4 0 181.4 41.7 1970 12 7.5 3.3 6 42.9 69.4 etc. etc. etc.

aberporthdata.txt

Page 27: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

ExtractTransform

Load

Page 28: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

[Whiteboard]

Page 29: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Not Designed for Test

Hosted in CloudNot Directly ExecutableHybrid CodeClosely Coupled

Page 30: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Few Tools

A library from MSabstractions too leaky

Local Test Runnerthis is useful

Page 31: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Few techniques

SQL unit testsfairly gruesome

Page 32: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Few workarounds

Google doesn’t help

Page 33: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Outside-in approach

Acceptance test outer loop

Unit test inner loop

Page 34: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Acceptance Test

Local Run Helper

Page 35: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 36: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 37: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

U-SQL Script TestHybrid code

U-SQL & C#

Data on file system

Page 38: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 39: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Responsibility of Script

Orchestrator or

Query

Page 40: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Seam U-SQL // C#

Inline code Nope!

Code-behindNah…

AssembliesNow you’re talking!

Page 41: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Substitute AssembliesCode is compiled for each execution

Duck typing

Substitute at runtime

Page 42: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 43: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 44: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 45: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Stub or Mock?Not directly availableFakes against file system

Page 46: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 47: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 48: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

User-Defined Objects

Page 49: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 50: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Leaky Abstraction

Use of StreamsTemporal CouplingStrange Idiom>1 Responsibility

Page 51: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 52: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Adapter layerTranslate between framework & domain

Page 53: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 54: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 55: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 56: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 57: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 58: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 59: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Domain Tests

Familiar Territory

Page 60: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 61: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit
Page 62: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

You may still need to Mock the Clock!

Page 63: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

What have we learnt?

Page 64: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Speed Run locallyControl Seams

Test doublesPrecision Small pieces

Clear purposeAdapters

Page 65: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

PatternsPatterns

Patterns

Page 66: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

ResourcesTesting Patterns github.com/bnathyuw/testing-patterns/wiki

Example implementation github.com/bnathyuw/weather-data-iii

Page 67: Matthew Butt Unit Testing the Hard Stuff · .NET Web API [Whiteboard] Designed for Test Directly Executable Object Oriented Abstractions DI. Techniques SOLID design Mocking ... Unit

Dank je wel!