Last active
December 29, 2015 12:29
-
-
Save robdmoore/7671127 to your computer and use it in GitHub Desktop.
NTestDataBuilder with inheritance within the classes being built
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Simpler, but you get all methods and get's unwieldy as the number of differences between the / number of sub classes grows | |
using System; | |
using NTestDataBuilder; | |
namespace ConsoleApplication4 | |
{ | |
class Program | |
{ | |
static void Main() | |
{ | |
var sports = ObjectMother.Cars.Sport | |
.WithExhaust(ExhaustSize.UberBig) | |
.WithName("Red Ferrari") | |
.Build(); | |
Console.WriteLine("{0}: exhaust {1}", sports.Name, sports.Exhaust); | |
var boring = ObjectMother.Cars.Boring | |
.WithSpeed(Speed.Slow) | |
.WithName("Grey VW Beetle") | |
.Build(); | |
Console.WriteLine("{0}: speed {1}", boring.Name, boring.Speed); | |
Console.ReadLine(); | |
} | |
} | |
public abstract class Car | |
{ | |
protected Car(string name) | |
{ | |
Name = name; | |
} | |
public string Name { get; private set; } | |
} | |
public class BoringCar : Car | |
{ | |
public BoringCar(string name, Speed speed) | |
: base(name) | |
{ | |
Speed = speed; | |
} | |
public Speed Speed { get; private set; } | |
} | |
public enum Speed | |
{ | |
Slow, | |
VerySlow, | |
UltraSlow | |
} | |
public class SportsCar : Car | |
{ | |
public SportsCar(string name, ExhaustSize exhaust) | |
: base(name) | |
{ | |
Exhaust = exhaust; | |
} | |
public ExhaustSize Exhaust { get; private set; } | |
} | |
public enum ExhaustSize | |
{ | |
Big, | |
ReallyBig, | |
UberBig | |
} | |
class CarBuilder<TCar> : TestDataBuilder<TCar, CarBuilder<TCar>> where TCar : Car | |
{ | |
public CarBuilder() | |
{ | |
Set(x => x.Name, "A car"); | |
Set(x => (x as BoringCar).Speed, Speed.UltraSlow); | |
Set(x => (x as SportsCar).Exhaust, ExhaustSize.ReallyBig); | |
} | |
public CarBuilder<TCar> WithName(string name) | |
{ | |
Set(x => x.Name, name); | |
return this; | |
} | |
public CarBuilder<TCar> WithSpeed(Speed speed) | |
{ | |
if (typeof (TCar) == typeof (BoringCar)) | |
{ | |
Set(x => (x as BoringCar).Speed, speed); | |
} | |
return this; | |
} | |
public CarBuilder<TCar> WithExhaust(ExhaustSize exhaust) | |
{ | |
if (typeof(TCar) == typeof(SportsCar)) | |
{ | |
Set(x => (x as SportsCar).Exhaust, exhaust); | |
} | |
return this; | |
} | |
protected override TCar BuildObject() | |
{ | |
if (typeof (TCar) == typeof (BoringCar)) | |
return new BoringCar(Get(x => x.Name), Get(x => (x as BoringCar).Speed)) as TCar; | |
if (typeof(TCar) == typeof(SportsCar)) | |
return new SportsCar(Get(x => x.Name), Get(x => (x as SportsCar).Exhaust)) as TCar; | |
throw new NotSupportedException(string.Format("Invalid TCar in CarBuilder: {0}", typeof(TCar).Name)); | |
} | |
} | |
static class ObjectMother | |
{ | |
public static class Cars | |
{ | |
public static CarBuilder<SportsCar> Sport | |
{ | |
get | |
{ | |
return new CarBuilder<SportsCar>(); | |
} | |
} | |
public static CarBuilder<BoringCar> Boring | |
{ | |
get | |
{ | |
return new CarBuilder<BoringCar>(); | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// More generic magic, but a much more maintainable solution | |
using System; | |
using NTestDataBuilder; | |
namespace ConsoleApplication4 | |
{ | |
class Program | |
{ | |
static void Main() | |
{ | |
var sports = ObjectMother.Cars.Sport | |
.WithExhaust(ExhaustSize.UberBig) | |
.WithName("Red Ferrari") | |
.Build(); | |
Console.WriteLine("{0}: exhaust {1}", sports.Name, sports.Exhaust); | |
var boring = ObjectMother.Cars.Boring | |
.WithSpeed(Speed.Slow) | |
.WithName("Grey VW Beetle") | |
.Build(); | |
Console.WriteLine("{0}: speed {1}", boring.Name, boring.Speed); | |
Console.ReadLine(); | |
} | |
} | |
public abstract class Car | |
{ | |
protected Car(string name) | |
{ | |
Name = name; | |
} | |
public string Name { get; private set; } | |
} | |
public class BoringCar : Car | |
{ | |
public BoringCar(string name, Speed speed) | |
: base(name) | |
{ | |
Speed = speed; | |
} | |
public Speed Speed { get; private set; } | |
} | |
public enum Speed | |
{ | |
Slow, | |
VerySlow, | |
UltraSlow | |
} | |
public class SportsCar : Car | |
{ | |
public SportsCar(string name, ExhaustSize exhaust) | |
: base(name) | |
{ | |
Exhaust = exhaust; | |
} | |
public ExhaustSize Exhaust { get; private set; } | |
} | |
public enum ExhaustSize | |
{ | |
Big, | |
ReallyBig, | |
UberBig | |
} | |
abstract class CarBuilder<TCar, TBuilder> : TestDataBuilder<TCar, TBuilder> | |
where TCar : Car | |
where TBuilder : CarBuilder<TCar, TBuilder> | |
{ | |
protected CarBuilder() | |
{ | |
Set(x => x.Name, "A car"); | |
} | |
protected TBuilder This() | |
{ | |
return this as TBuilder; | |
} | |
public TBuilder WithName(string name) | |
{ | |
Set(x => x.Name, name); | |
return This(); | |
} | |
} | |
class SportsCarBuilder : CarBuilder<SportsCar, SportsCarBuilder> | |
{ | |
public SportsCarBuilder() | |
{ | |
Set(x => x.Exhaust, ExhaustSize.ReallyBig); | |
} | |
public SportsCarBuilder WithExhaust(ExhaustSize exhaust) | |
{ | |
Set(x => x.Exhaust, exhaust); | |
return this; | |
} | |
protected override SportsCar BuildObject() | |
{ | |
return new SportsCar(Get(x => x.Name), Get(x => x.Exhaust)); | |
} | |
} | |
class BoringCarBuilder : CarBuilder<BoringCar, BoringCarBuilder> | |
{ | |
public BoringCarBuilder() | |
{ | |
Set(x => x.Speed, Speed.UltraSlow); | |
} | |
public BoringCarBuilder WithSpeed(Speed speed) | |
{ | |
Set(x => x.Speed, speed); | |
return this; | |
} | |
protected override BoringCar BuildObject() | |
{ | |
return new BoringCar(Get(x => x.Name), Get(x => x.Speed)); | |
} | |
} | |
static class ObjectMother | |
{ | |
public static class Cars | |
{ | |
public static SportsCarBuilder Sport | |
{ | |
get | |
{ | |
return new SportsCarBuilder(); | |
} | |
} | |
public static BoringCarBuilder Boring | |
{ | |
get | |
{ | |
return new BoringCarBuilder(); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment