14
A Better Way to Setup Test Data Poya Manouchehri @PoyaManouchehri [email protected] http://askpoya.wordpress.com/

Setup testdata

Embed Size (px)

DESCRIPTION

A collection of techniques for creating unit test data more concisely and easily.

Citation preview

Page 1: Setup testdata

A Better Way to SetupTest DataPoya Manouchehri

@[email protected]://askpoya.wordpress.com/

Page 2: Setup testdata

1. Intent is Unclear:• What is 160?• Is nationality important?

2. Test is Brittle:• Changing the constructor will break many tests

[Test]public void GivenAPersonUnder16_WhenAssigningADriverLicense_ThenAnExceptionIsThrown(){ // Arrange var sarah = new Person("Sarah", "Smith", DateTime.Today.AddYears(-15), 160, "Australian");

// Act / Assert Assert.Throws<InvalidOperationException>(() => sarah.AssignDriverLicense(DriverLicenseType.Automatic));}

Page 3: Setup testdata

public static partial class ObjectMother{ public static class Persons { public static Person FifteenYearOldSarah { get { return new Person("Sarah", "Smith", DateTime.Today.AddYears(-17), 160, "Australian"); } }

public static Person BrazilianRafael { get { return new Person("Rafael", "Gomez", new DateTime(1985, 12 , 2), 177, “Brazilian") } } }}

Object Mother Pattern

Page 4: Setup testdata

[Test]public void GivenAPersonUnder16_WhenAssigningADriverLicense_ThenAnExceptionIsThrown(){ var sarah = ObjectMother.Persons.FifteenYearOldSarah;

Assert.Throws<InvalidOperationException>(() => sarah.AssignDriverLicense(DriverLicenseType.Automatic));}

Object Mother Pattern

Page 5: Setup testdata

var person = new PersonBuilder() .WithName("Michael", "Jackson") .BornOn(new DateTime(1958, 8, 29)) .WithHeight(175) .WithNationality("American") .WhoHasDriverLicense(DriverLicenseType.Truck) .Build();

Builder Pattern

Page 6: Setup testdata

[Test]public void GivenAPersonUnder16_WhenAssigningADriverLicense_ThenAnExceptionIsThrown(){ var person = new PersonBuilder() .BornOn(DateTime.Today.AddYears(-15)) .Build();

Assert.Throws<InvalidOperationException>(() => person.AssignDriverLicense(DriverLicenseType.Automatic));}

Builder Pattern

Page 7: Setup testdata

[Test]public void GivenAPersonUnder16_WhenAssigningADriverLicense_ThenAnExceptionIsThrown(){ var person = ObjectMother.Persons.Sarah .BornOn(DateTime.Today.AddYears(-15)) .Build();

Assert.Throws<InvalidOperationException>(() => person.AssignDriverLicense(DriverLicenseType.Automatic));}

Builder Pattern

Page 8: Setup testdata

var people = PersonBuilder.CreateListOfSize(10) .All().Do(p => p.WithNationality("Australian")) .TheFirst(2).Do(p => p.BornOn(new DateTime(1980, 1, 1))) .TheNext(3).Do(p => p.BornOn(new DateTime(1974, 10, 15))) .Random(2).Do(p => p.WithHeight(180)) .BuildList<Person, PersonBuilder>();

Building Collections with NBuilder

var people = new[]{ new PersonBuilder().WithNationality("Australian").BornOn(new DateTime(1980, 1, 1)).Build(), new PersonBuilder().WithNationality("Australian").BornOn(new DateTime(1980, 1, 1)) .WithHeight(180).Build(), new PersonBuilder().WithNationality("Australian").BornOn(new DateTime(1974, 10, 15)).Build(), new PersonBuilder().WithNationality("Australian").BornOn(new DateTime(1974, 10, 15)) .WithHeight(180).Build(), new PersonBuilder().WithNationality("Australian").BornOn(new DateTime(1974, 10, 15)).Build()};

Page 9: Setup testdata

public class TransportCentre{ ...

public void PerformTruckDrivingTest(Person person) { // Do the test

person.AssignDriverLicense(DriverLicenseType.Truck); }}

Building Mocks with NSubstitute

Page 10: Setup testdata

[Test]public void GivenAPerson_WhenTruckDrivingTestIsCompleted_ThenThePersonIsAssignedALicense(){ var person = ObjectMother.Persons.John.Build(); var transportCentre = ObjectMother.TransportCentres.BrisbaneCityCentre.Build();

transportCentre.PerformTruckDrivingTest(person);

Assert.That(person.DriverLicenseType, Is.EqualTo(DriverLicenseType.Truck));}

What’s the actual “Unit” under test?• PerformTruckDrivingTest()• Not Person.AssignDriverLicense()

Building Mocks with NSubstitute

Page 11: Setup testdata

[Test]public void GivenAPerson_WhenTruckDrivingTestIsCompleted_ThenThePersonIsAssignedALicense(){ var person = ObjectMother.Persons.John.AsProxy().Build(); var transportCentre = ObjectMother.TransportCentres.BrisbaneCityCentre.Build();

transportCentre.PerformTruckDrivingTest(person);

person.Received().AssignDriverLicense(DriverLicenseType.Truck);}

Building Mocks with NSubstitute

What’s the actual “Unit” under test?• PerformTruckDrivingTest()• Not Person.AssignDriverLicense()

Page 12: Setup testdata

Building Mocks with NSubstitute

Caveats:• Requires a protected parameteress constructor• Requires the virtual keyword for any properties or methods that

need to be mocked

Page 13: Setup testdata

GitHub: https://github.com/robdmoore/NTestDataBuilder

Twitter: @robdmoore

NTestDataBuilder

Page 14: Setup testdata

Questions