9
I Use This!
Activity Not Available

News

Posted almost 11 years ago by [email protected] (Nikos Baxevanis)
The complete list can be found here. AutoFixture.Auto[Moq/RhinoMocks/FakeItEasy/NSubstitute] What is AutoFixture AutoMoq? Differences between Moq and AutoFixture How to verify a method was called Using verify to confirm expected parameter ... [More] values in Moq’s Mock class Creating a hybrid of a Mock and an Anonymous object using Moq and AutoFixture Test a class that takes a Factory Repetitive code in Unit Tests Integration Test an application using Castle Windsor AutoFixture as an Auto-mocking Container vs Auto-mocking differences Create an instance of a type that contains properties with an interface type How to return results from injected services in an instantiated object Mocked methods returning a Frozen instance Proper use of AutoFixture AutoMoq AutoData Theories with AutoFixture using manual fakes How to express a Unit Test declaratively? Imperative to Declarative Unit Test Auto-mocking using FakeItEasy Auto-mocking the SUT AutoFixture.Idioms When I pass input to the parameter x of a method, supplying the other parameters anonymously, the result is .. Simplifing Unit Testing DDD Value objects Equality Verify invalid constructor parameters AutoFixture.Xunit Integration Test an application using Castle Windsor AutoFixture with ‘weak’ types Proxies in data integration tests AutoFixture with derived types Mocked methods returning a Frozen instance Proper use of AutoFixture AutoMoq How to express a Unit Test declaratively Imperative to Declarative Unit Test Auto-mocking using FakeItEasy What are the principles behind AutoFixture’s declarative way of setting up a fixture? PropertyDataAttribute and heterogeneous parameters Customizations How to create a list of types with predefined values How to set a private setter of an Automatic Property by calling a method Generate anonymous number for string property Execute a delegate at object creation time How to limit the length of generated strings Integration Test an application using Castle Windsor Selecting the greediest constructor by default How to call a base method for all instances of classes that inherit from it Creating ASP.NET MVC Controller instances without setting property values How to generate objects when there are multiple paths to a child entity AutoFixture with ‘weak’ types Proxies in data integration tests Supplying values for inherited properties Mocked methods returning a Frozen instance Creating ASP.NET MVC Controller instances Using Customize with seeded property PropertyTypeOmitter (System.Runtime.Serialization.ExtensionDataObject example) Customizing constructor parameter values Ignore virtual properties Creating an ISpecimenBuilder for a type Imperative to Declarative Unit Test Freeze, Inject How to verify a method was called How to Freeze a Null Reference AutoFixture with ‘weak’ types AutoFixture with derived types Auto-mocking using FakeItEasy Supply a known value for one constructor parameter Likeness, Likeness as Resemblance Compare only matching properties Likeness applied to sequences Custom Assertion Using verify to confirm expected parameter values in Moq’s Mock class Likeness applied to sequences How to use ‘EqualsWhen’ Refactoring Minimizing the Arrange phase Repetitive code in Unit Tests Imperative to Declarative Unit Test [Less]
Posted almost 11 years ago by [email protected] (Nikos Baxevanis)
The complete list can be found here. AutoFixture.Auto[Moq/RhinoMocks/FakeItEasy/NSubstitute] What is AutoFixture AutoMoq? Differences between Moq and AutoFixture How to verify a method was called Using verify to confirm expected parameter values ... [More] in Moq’s Mock class Creating a hybrid of a Mock and an Anonymous object using Moq and AutoFixture Test a class that takes a Factory Repetitive code in Unit Tests Integration Test an application using Castle Windsor AutoFixture as an Auto-mocking Container vs Auto-mocking differences Create an instance of a type that contains properties with an interface type How to return results from injected services in an instantiated object Mocked methods returning a Frozen instance Proper use of AutoFixture AutoMoq AutoData Theories with AutoFixture using manual fakes How to express a Unit Test declaratively? Imperative to Declarative Unit Test Auto-mocking using FakeItEasy Auto-mocking the SUT AutoFixture.Idioms When I pass input to the parameter x of a method, supplying the other parameters anonymously, the result is .. Simplifing Unit Testing DDD Value objects Equality Verify invalid constructor parameters AutoFixture.Xunit Integration Test an application using Castle Windsor AutoFixture with ‘weak’ types Proxies in data integration tests AutoFixture with derived types Mocked methods returning a Frozen instance Proper use of AutoFixture AutoMoq How to express a Unit Test declaratively Imperative to Declarative Unit Test Auto-mocking using FakeItEasy What are the principles behind AutoFixture’s declarative way of setting up a fixture? PropertyDataAttribute and heterogeneous parameters Customizations How to create a list of types with predefined values How to set a private setter of an Automatic Property by calling a method Generate anonymous number for string property Execute a delegate at object creation time How to limit the length of generated strings Integration Test an application using Castle Windsor Selecting the greediest constructor by default How to call a base method for all instances of classes that inherit from it Creating ASP.NET MVC Controller instances without setting property values How to generate objects when there are multiple paths to a child entity AutoFixture with ‘weak’ types Proxies in data integration tests Supplying values for inherited properties Mocked methods returning a Frozen instance Creating ASP.NET MVC Controller instances Using Customize with seeded property PropertyTypeOmitter (System.Runtime.Serialization.ExtensionDataObject example) Customizing constructor parameter values Ignore virtual properties Creating an ISpecimenBuilder for a type Imperative to Declarative Unit Test Freeze, Inject How to verify a method was called How to Freeze a Null Reference AutoFixture with ‘weak’ types AutoFixture with derived types Auto-mocking using FakeItEasy Supply a known value for one constructor parameter Likeness, Likeness as Resemblance Compare only matching properties Likeness applied to sequences Custom Assertion Using verify to confirm expected parameter values in Moq’s Mock class Likeness applied to sequences How to use ‘EqualsWhen’ Refactoring Minimizing the Arrange phase Repetitive code in Unit Tests Imperative to Declarative Unit Test [Less]
Posted about 11 years ago by Enrico Campidoglio
If you’ve been using AutoFixture in your tests for more than a while, chances are you’ve already come across the concept of customizations. If you’re not familiar with it, let me give you a quick introduction: A customization is a group of settings that, when applied to a given Fixture object, control the way AutoFixture [...]
Posted about 11 years ago
If you’ve been using AutoFixture in your tests for more than a while, chances are you’ve already come across the concept of customizations. If you’re not familiar with it, let me give you a quick introduction: A customization is a group of ... [More] settings that, when applied to a given Fixture object, control the way AutoFixture will create instances for the types requested through that Fixture. At this point you might find yourself feeling an irresistible urge to know everything there’s to know about customizations. If that’s the case, don’t worry. There are a few resources online where you learn more about them. For example, I wrote about how to take advantage of customizations to group together test data related to specific scenarios. In this post I’m going to talk about something different which, in a sense, is quite the opposite of that: how to write general-purpose customizations. A (user) story about cooking It’s hard to talk about test data without a bit of context. So, for the sake of this post, I thought we would pretend to be working on a somewhat realistic project. The system we’re going to build is an online catalogue of food recipies. The domain, at the very basic level, consists of three concepts: Cookbook Recipes Ingredients Now, let’s imagine that in our backlog of requirements we have one where the user wishes to be able to search for recepies that contain a specific set of ingredients. Or in other words: As a foodie, I want to know which recipes I can prepare with the ingredients I have, so that I can get the best value for my groceries. From the tests… As usual, we start out by translating the requirement at hand into a set of acceptance tests. In order do that, we need to tell AutoFixture how we’d like the test data for our domain model to be generated. For this particular scenario, we need every Ingredient created in the test fixture to be randomly chosen from a fixed pool of objects. That way we can ensure that all recepies in the cookbook will be made up of the same set of ingredients. Here’s how such a customization would look like: public class RandomIngredientsFromFixedSequence : ICustomization { private readonly Random randomizer = new Random(); private IEnumerable sequence; public void Customize(IFixture fixture) { InitializeIngredientSequence(fixture); fixture.Register(PickRandomIngredientFromSequence); } private void InitializeIngredientSequence(IFixture fixture) { this.sequence = fixture.CreateMany(); } private Ingredient PickRandomIngredientFromSequence() { var randomIndex = this.randomizer.Next(0, sequence.Count() - 1); return sequence.ElementAt(randomIndex); } } Here we’re creating a pool of ingredients and telling AutoFixture to randomly pick one of those every time it needs to create an Ingredient object by using the Fixture.Register method. Since we’ll be using Xunit as our test runner, you can take advantage of the AutoFixture Data Theories to keep our tests succinct by using AutoFixture in a declarative fashion. In order to do so, we need to write an xUnit Data Theory attribute that tells AutoFixture to use our new customization: public class CookbookAutoDataAttribute : AutoDataAttribute { public CookbookAutoDataAttribute() : base(new Fixture().Customize( new RandomIngredientsFromFixedSequence()))) { } } If you prefer to use AutoFixture directly in your tests, the imperative equivalent of the above is: var fixture = new Fixture(); fixture.Customize(new RandomIngredientsFromFixedSequence()); At this point, we can finally start writing the acceptance tests to satisfy our original requirement: public class When_searching_for_recipies_by_ingredients { [Theory, CookbookAutoData] public void Should_only_return_recipes_with_a_specific_ingredient( Cookbook sut, Ingredient ingredient) { // When var recipes = sut.FindRecipies(ingredient); // Then Assert.True(recipes.All(r => r.Ingredients.Contains(ingredient))); } [Theory, CookbookAutoData] public void Should_include_new_recipes_with_a_specific_ingredient( Cookbook sut, Ingredient ingredient, Recipe recipeWithIngredient) { // Given sut.AddRecipe(recipeWithIngredient); // When var recipes = sut.FindRecipies(ingredient); // Then Assert.Contains(recipeWithIngredient, recipes); } } Notice that during these tests AutoFixture will have to create Ingredient objects in a couple of different ways: indirectly when constructing Recipe objects associated to a Cookbook directly when providing arguments for the test parameters As far as AutoFixture is concerned, it doesn’t really matter which code path leads to the creation of ingredients. The algorithm provided by the RandomIngredientsFromFixedSequence customization will apply in all situations. …to the implementation After a couple of Red-Green-Refactor cycles spawned from the above tests, it’s not completely unlikely that we might end up with some production code similar to this: // Cookbook.cs public class Cookbook { private readonly ICollection recipes; public Cookbook(IEnumerable recipes) { this.recipes = new List(recipes); } public IEnumerable FindRecipies(params Ingredient[] ingredients) { return recipes.Where(r => r.Ingredients.Intersect(ingredients).Any()); } public void AddRecipe(Recipe recipe) { this.recipes.Add(recipe); } } // Recipe.cs public class Recipe { public readonly IEnumerable Ingredients; public Recipe(IEnumerable ingredients) { this.Ingredients = ingredients; } } // Ingredient.cs public class Ingredient { public readonly string Name; public Ingredient(string name) { this.Name = name; } } Nice and simple. But let’s not stop here. It’s time to take it a bit further. An opportunity for generalization Given the fact that we started working from a very concrete requirement, it’s only natural that the RandomIngredientsFromFixedSequence customization we came up at with encapsulates a behavior that is specific to the scenario at hand. However, if we take a closer look we might notice the following: The only part of the algorithm that is specific to the original scenario is the type of the objects being created. The rest can easily be applied whenever you want to create objects that are picked at random from a predefined pool. An opportunity for writing a general-purpose customization has just presented itself. We can’t let it slip. Let’s see what happens if we extract the Ingredient type into a generic argument and remove all references to the word “ingredient”: public class RandomFromFixedSequence : ICustomization { private readonly Random randomizer = new Random(); private IEnumerable sequence; public void Customize(IFixture fixture) { InitializeSequence(fixture); fixture.Register(PickRandomItemFromSequence); } private void InitializeSequence(IFixture fixture) { this.sequence = fixture.CreateMany(); } private T PickRandomItemFromSequence() { var randomIndex = this.randomizer.Next(0, sequence.Count() - 1); return sequence.ElementAt(randomIndex); } } Voilà. We just turned our scenario-specific customization into a pluggable algorithm that changes the way objects of any type are going to be generated by AutoFixture. In this case the algorithm will create items by picking them at random from a fixed sequence of T. The CookbookAutoDataAttribute can easily changed to use the general-purpose version of the customization by closing the generic argument with the Ingredient type: public class CookbookAutoDataAttribute : AutoDataAttribute { public CookbookAutoDataAttribute() : base(new Fixture().Customize( new RandomFromFixedSequence()))) { } } The same is true if you’re using AutoFixture imperatively: var fixture = new Fixture(); fixture.Customize(new RandomFromFixedSequence()); Wrapping up As I said before, customizations are a great way to set up test data for a specific scenario. Sometimes these configurations turn out to be useful in more than just one situation. When such opportunity arises, it’s often a good idea to separate out the parts that are specific to a particular context and turn them into parameters. This allows the customization to become a reusable strategy for controlling AutoFixture’s behavior across entire test suites. [Less]
Posted about 11 years ago
If you’ve been using AutoFixture in your tests for more than a while, chances are you’ve already come across the concept of customizations. If you’re not familiar with it, let me give you a quick introduction: A customization is a group of ... [More] settings that, when applied to a given Fixture object, control the way AutoFixture will create instances for the types requested through that Fixture. At this point you might find yourself feeling an irresistible urge to know everything there’s to know about customizations. If that’s the case, don’t worry. There are a few resources online where you learn more about them. For example, I wrote about how to take advantage of customizations to group together test data related to specific scenarios. In this post I’m going to talk about something different which, in a sense, is quite the opposite of that: how to write general-purpose customizations. A (user) story about cooking It’s hard to talk about test data without a bit of context. So, for the sake of this post, I thought we would pretend to be working on a somewhat realistic project. The system we’re going to build is an online catalogue of food recipies. The domain, at the very basic level, consists of three concepts: Cookbook Recipes Ingredients Now, let’s imagine that in our backlog of requirements we have one where the user wishes to be able to search for recepies that contain a specific set of ingredients. Or in other words: As a foodie, I want to know which recipes I can prepare with the ingredients I have, so that I can get the best value for my groceries. From the tests… As usual, we start out by translating the requirement at hand into a set of acceptance tests. In order do that, we need to tell AutoFixture how we’d like the test data for our domain model to be generated. For this particular scenario, we need every Ingredient created in the test fixture to be randomly chosen from a fixed pool of objects. That way we can ensure that all recepies in the cookbook will be made up of the same set of ingredients. Here’s how such a customization would look like: public class RandomIngredientsFromFixedSequence : ICustomization { private readonly Random randomizer = new Random(); private IEnumerable<Ingredient> sequence; public void Customize(IFixture fixture) { InitializeIngredientSequence(fixture); fixture.Register(PickRandomIngredientFromSequence); } private void InitializeIngredientSequence(IFixture fixture) { this.sequence = fixture.CreateMany<Ingredient>(); } private Ingredient PickRandomIngredientFromSequence() { var randomIndex = this.randomizer.Next(0, sequence.Count()); return sequence.ElementAt(randomIndex); } } Here we’re creating a pool of ingredients and telling AutoFixture to randomly pick one of those every time it needs to create an Ingredient object by using the Fixture.Register method. Since we’ll be using Xunit as our test runner, you can take advantage of the AutoFixture Data Theories to keep our tests succinct by using AutoFixture in a declarative fashion. In order to do so, we need to write an xUnit Data Theory attribute that tells AutoFixture to use our new customization: public class CookbookAutoDataAttribute : AutoDataAttribute { public CookbookAutoDataAttribute() : base(new Fixture().Customize( new RandomIngredientsFromFixedSequence()))) { } } If you prefer to use AutoFixture directly in your tests, the imperative equivalent of the above is: var fixture = new Fixture(); fixture.Customize(new RandomIngredientsFromFixedSequence()); At this point, we can finally start writing the acceptance tests to satisfy our original requirement: public class When_searching_for_recipies_by_ingredients { [Theory, CookbookAutoData] public void Should_only_return_recipes_with_a_specific_ingredient( Cookbook sut, Ingredient ingredient) { // When var recipes = sut.FindRecipies(ingredient); // Then Assert.True(recipes.All(r => r.Ingredients.Contains(ingredient))); } [Theory, CookbookAutoData] public void Should_include_new_recipes_with_a_specific_ingredient( Cookbook sut, Ingredient ingredient, Recipe recipeWithIngredient) { // Given sut.AddRecipe(recipeWithIngredient); // When var recipes = sut.FindRecipies(ingredient); // Then Assert.Contains(recipeWithIngredient, recipes); } } Notice that during these tests AutoFixture will have to create Ingredient objects in a couple of different ways: indirectly when constructing Recipe objects associated to a Cookbook directly when providing arguments for the test parameters As far as AutoFixture is concerned, it doesn’t really matter which code path leads to the creation of ingredients. The algorithm provided by the RandomIngredientsFromFixedSequence customization will apply in all situations. …to the implementation After a couple of Red-Green-Refactor cycles spawned from the above tests, it’s not completely unlikely that we might end up with some production code similar to this: // Cookbook.cs public class Cookbook { private readonly ICollection<Recipe> recipes; public Cookbook(IEnumerable<Recipe> recipes) { this.recipes = new List<Recipe>(recipes); } public IEnumerable<Recipe> FindRecipies(params Ingredient[] ingredients) { return recipes.Where(r => r.Ingredients.Intersect(ingredients).Any()); } public void AddRecipe(Recipe recipe) { this.recipes.Add(recipe); } } // Recipe.cs public class Recipe { public readonly IEnumerable<Ingredient> Ingredients; public Recipe(IEnumerable<Ingredient> ingredients) { this.Ingredients = ingredients; } } // Ingredient.cs public class Ingredient { public readonly string Name; public Ingredient(string name) { this.Name = name; } } Nice and simple. But let’s not stop here. It’s time to take it a bit further. An opportunity for generalization Given the fact that we started working from a very concrete requirement, it’s only natural that the RandomIngredientsFromFixedSequence customization we came up at with encapsulates a behavior that is specific to the scenario at hand. However, if we take a closer look we might notice the following: The only part of the algorithm that is specific to the original scenario is the type of the objects being created. The rest can easily be applied whenever you want to create objects that are picked at random from a predefined pool. An opportunity for writing a general-purpose customization has just presented itself. We can’t let it slip. Let’s see what happens if we extract the Ingredient type into a generic argument and remove all references to the word “ingredient”: public class RandomFromFixedSequence<T> : ICustomization { private readonly Random randomizer = new Random(); private IEnumerable<T> sequence; public void Customize(IFixture fixture) { InitializeSequence(fixture); fixture.Register(PickRandomItemFromSequence); } private void InitializeSequence(IFixture fixture) { this.sequence = fixture.CreateMany<T>(); } private T PickRandomItemFromSequence() { var randomIndex = this.randomizer.Next(0, sequence.Count()); return sequence.ElementAt(randomIndex); } } Voilà. We just turned our scenario-specific customization into a pluggable algorithm that changes the way objects of any type are going to be generated by AutoFixture. In this case the algorithm will create items by picking them at random from a fixed sequence of T. The CookbookAutoDataAttribute can easily changed to use the general-purpose version of the customization by closing the generic argument with the Ingredient type: public class CookbookAutoDataAttribute : AutoDataAttribute { public CookbookAutoDataAttribute() : base(new Fixture().Customize( new RandomFromFixedSequence<Ingredient>()))) { } } The same is true if you’re using AutoFixture imperatively: var fixture = new Fixture(); fixture.Customize(new RandomFromFixedSequence<Ingredient>()); Wrapping up As I said before, customizations are a great way to set up test data for a specific scenario. Sometimes these configurations turn out to be useful in more than just one situation. When such opportunity arises, it’s often a good idea to separate out the parts that are specific to a particular context and turn them into parameters. This allows the customization to become a reusable strategy for controlling AutoFixture’s behavior across entire test suites. [Less]
Posted about 11 years ago
If you’ve been using AutoFixture in your tests for more than a while, chances are you’ve already come across the concept of customizations. If you’re not familiar with it, let me give you a quick introduction: A customization is a group of ... [More] settings that, when applied to a given Fixture object, control the way AutoFixture will create instances for the types requested through that Fixture. At this point you might find yourself feeling an irresistible urge to know everything there’s to know about customizations. If that’s the case, don’t worry. There are a few resources online where you learn more about them. For example, I wrote about how to take advantage of customizations to group together test data related to specific scenarios. In this post I’m going to talk about something different which, in a sense, is quite the opposite of that: how to write general-purpose customizations. A (user) story about cooking It’s hard to talk about test data without a bit of context. So, for the sake of this post, I thought we would pretend to be working on a somewhat realistic project. The system we’re going to build is an online catalogue of food recipies. The domain, at the very basic level, consists of three concepts: Cookbook Recipes Ingredients Now, let’s imagine that in our backlog of requirements we have one where the user wishes to be able to search for recepies that contain a specific set of ingredients. Or in other words: As a foodie, I want to know which recipes I can prepare with the ingredients I have, so that I can get the best value for my groceries. From the tests… As usual, we start out by translating the requirement at hand into a set of acceptance tests. In order do that, we need to tell AutoFixture how we’d like the test data for our domain model to be generated. For this particular scenario, we need every Ingredient created in the test fixture to be randomly chosen from a fixed pool of objects. That way we can ensure that all recepies in the cookbook will be made up of the same set of ingredients. Here’s how such a customization would look like: public class RandomIngredientsFromFixedSequence : ICustomization { private readonly Random randomizer = new Random(); private IEnumerable<Ingredient> sequence; public void Customize(IFixture fixture) { InitializeIngredientSequence(fixture); fixture.Register(PickRandomIngredientFromSequence); } private void InitializeIngredientSequence(IFixture fixture) { this.sequence = fixture.CreateMany<Ingredient>(); } private Ingredient PickRandomIngredientFromSequence() { var randomIndex = this.randomizer.Next(0, sequence.Count()); return sequence.ElementAt(randomIndex); } } Here we’re creating a pool of ingredients and telling AutoFixture to randomly pick one of those every time it needs to create an Ingredient object by using the Fixture.Register method. Since we’ll be using Xunit as our test runner, you can take advantage of the AutoFixture Data Theories to keep our tests succinct by using AutoFixture in a declarative fashion. In order to do so, we need to write an xUnit Data Theory attribute that tells AutoFixture to use our new customization: public class CookbookAutoDataAttribute : AutoDataAttribute { public CookbookAutoDataAttribute() : base(new Fixture().Customize( new RandomIngredientsFromFixedSequence()))) { } } If you prefer to use AutoFixture directly in your tests, the imperative equivalent of the above is: var fixture = new Fixture(); fixture.Customize(new RandomIngredientsFromFixedSequence()); At this point, we can finally start writing the acceptance tests to satisfy our original requirement: public class When_searching_for_recipies_by_ingredients { [Theory, CookbookAutoData] public void Should_only_return_recipes_with_a_specific_ingredient( Cookbook sut, Ingredient ingredient) { // When var recipes = sut.FindRecipies(ingredient); // Then Assert.True(recipes.All(r => r.Ingredients.Contains(ingredient))); } [Theory, CookbookAutoData] public void Should_include_new_recipes_with_a_specific_ingredient( Cookbook sut, Ingredient ingredient, Recipe recipeWithIngredient) { // Given sut.AddRecipe(recipeWithIngredient); // When var recipes = sut.FindRecipies(ingredient); // Then Assert.Contains(recipeWithIngredient, recipes); } } Notice that during these tests AutoFixture will have to create Ingredient objects in a couple of different ways: indirectly when constructing Recipe objects associated to a Cookbook directly when providing arguments for the test parameters As far as AutoFixture is concerned, it doesn’t really matter which code path leads to the creation of ingredients. The algorithm provided by the RandomIngredientsFromFixedSequence customization will apply in all situations. …to the implementation After a couple of Red-Green-Refactor cycles spawned from the above tests, it’s not completely unlikely that we might end up with some production code similar to this: // Cookbook.cs public class Cookbook { private readonly ICollection<Recipe> recipes; public Cookbook(IEnumerable<Recipe> recipes) { this.recipes = new List<Recipe>(recipes); } public IEnumerable<Recipe> FindRecipies(params Ingredient[] ingredients) { return recipes.Where(r => r.Ingredients.Intersect(ingredients).Any()); } public void AddRecipe(Recipe recipe) { this.recipes.Add(recipe); } } // Recipe.cs public class Recipe { public readonly IEnumerable<Ingredient> Ingredients; public Recipe(IEnumerable<Ingredient> ingredients) { this.Ingredients = ingredients; } } // Ingredient.cs public class Ingredient { public readonly string Name; public Ingredient(string name) { this.Name = name; } } Nice and simple. But let’s not stop here. It’s time to take it a bit further. An opportunity for generalization Given the fact that we started working from a very concrete requirement, it’s only natural that the RandomIngredientsFromFixedSequence customization we came up at with encapsulates a behavior that is specific to the scenario at hand. However, if we take a closer look we might notice the following: The only part of the algorithm that is specific to the original scenario is the type of the objects being created. The rest can easily be applied whenever you want to create objects that are picked at random from a predefined pool. An opportunity for writing a general-purpose customization has just presented itself. We can’t let it slip. Let’s see what happens if we extract the Ingredient type into a generic argument and remove all references to the word “ingredient”: public class RandomFromFixedSequence<T> : ICustomization { private readonly Random randomizer = new Random(); private IEnumerable<T> sequence; public void Customize(IFixture fixture) { InitializeSequence(fixture); fixture.Register(PickRandomItemFromSequence); } private void InitializeSequence(IFixture fixture) { this.sequence = fixture.CreateMany<T>(); } private T PickRandomItemFromSequence() { var randomIndex = this.randomizer.Next(0, sequence.Count()); return sequence.ElementAt(randomIndex); } } Voilà. We just turned our scenario-specific customization into a pluggable algorithm that changes the way objects of any type are going to be generated by AutoFixture. In this case the algorithm will create items by picking them at random from a fixed sequence of T. The CookbookAutoDataAttribute can easily changed to use the general-purpose version of the customization by closing the generic argument with the Ingredient type: public class CookbookAutoDataAttribute : AutoDataAttribute { public CookbookAutoDataAttribute() : base(new Fixture().Customize( new RandomFromFixedSequence<Ingredient>()))) { } } The same is true if you’re using AutoFixture imperatively: var fixture = new Fixture(); fixture.Customize(new RandomFromFixedSequence<Ingredient>()); Wrapping up As I said before, customizations are a great way to set up test data for a specific scenario. Sometimes these configurations turn out to be useful in more than just one situation. When such opportunity arises, it’s often a good idea to separate out the parts that are specific to a particular context and turn them into parameters. This allows the customization to become a reusable strategy for controlling AutoFixture’s behavior across entire test suites. [Less]
Posted about 11 years ago
If you’ve been using AutoFixture in your tests for more than a while, chances are you’ve already come across the concept of customizations. If you’re not familiar with it, let me give you a quick introduction: A customization is a group of ... [More] settings that, when applied to a given Fixture object, control the way AutoFixture will create instances for the types requested through that Fixture. At this point you might find yourself feeling an irresistible urge to know everything there’s to know about customizations. If that’s the case, don’t worry. There are a few resources online where you learn more about them. For example, I wrote about how to take advantage of customizations to group together test data related to specific scenarios. In this post I’m going to talk about something different which, in a sense, is quite the opposite of that: how to write general-purpose customizations. A (user) story about cooking It’s hard to talk about test data without a bit of context. So, for the sake of this post, I thought we would pretend to be working on a somewhat realistic project. The system we’re going to build is an online catalogue of food recipies. The domain, at the very basic level, consists of three concepts: Cookbook Recipes Ingredients Now, let’s imagine that in our backlog of requirements we have one where the user wishes to be able to search for recepies that contain a specific set of ingredients. Or in other words: As a foodie, I want to know which recipes I can prepare with the ingredients I have, so that I can get the best value for my groceries. From the tests… As usual, we start out by translating the requirement at hand into a set of acceptance tests. In order do that, we need to tell AutoFixture how we’d like the test data for our domain model to be generated. For this particular scenario, we need every Ingredient created in the test fixture to be randomly chosen from a fixed pool of objects. That way we can ensure that all recepies in the cookbook will be made up of the same set of ingredients. Here’s how such a customization would look like: public class RandomIngredientsFromFixedSequence : ICustomization { private readonly Random randomizer = new Random(); private IEnumerable<Ingredient> sequence; public void Customize(IFixture fixture) { InitializeIngredientSequence(fixture); fixture.Register(PickRandomIngredientFromSequence); } private void InitializeIngredientSequence(IFixture fixture) { this.sequence = fixture.CreateMany<Ingredient>(); } private Ingredient PickRandomIngredientFromSequence() { var randomIndex = this.randomizer.Next(0, sequence.Count()); return sequence.ElementAt(randomIndex); } } Here we’re creating a pool of ingredients and telling AutoFixture to randomly pick one of those every time it needs to create an Ingredient object by using the Fixture.Register method. Since we’ll be using Xunit as our test runner, you can take advantage of the AutoFixture Data Theories to keep our tests succinct by using AutoFixture in a declarative fashion. In order to do so, we need to write an xUnit Data Theory attribute that tells AutoFixture to use our new customization: public class CookbookAutoDataAttribute : AutoDataAttribute { public CookbookAutoDataAttribute() : base(new Fixture().Customize( new RandomIngredientsFromFixedSequence()))) { } } If you prefer to use AutoFixture directly in your tests, the imperative equivalent of the above is: var fixture = new Fixture(); fixture.Customize(new RandomIngredientsFromFixedSequence()); At this point, we can finally start writing the acceptance tests to satisfy our original requirement: public class When_searching_for_recipies_by_ingredients { [Theory, CookbookAutoData] public void Should_only_return_recipes_with_a_specific_ingredient( Cookbook sut, Ingredient ingredient) { // When var recipes = sut.FindRecipies(ingredient); // Then Assert.True(recipes.All(r => r.Ingredients.Contains(ingredient))); } [Theory, CookbookAutoData] public void Should_include_new_recipes_with_a_specific_ingredient( Cookbook sut, Ingredient ingredient, Recipe recipeWithIngredient) { // Given sut.AddRecipe(recipeWithIngredient); // When var recipes = sut.FindRecipies(ingredient); // Then Assert.Contains(recipeWithIngredient, recipes); } } Notice that during these tests AutoFixture will have to create Ingredient objects in a couple of different ways: indirectly when constructing Recipe objects associated to a Cookbook directly when providing arguments for the test parameters As far as AutoFixture is concerned, it doesn’t really matter which code path leads to the creation of ingredients. The algorithm provided by the RandomIngredientsFromFixedSequence customization will apply in all situations. …to the implementation After a couple of Red-Green-Refactor cycles spawned from the above tests, it’s not completely unlikely that we might end up with some production code similar to this: // Cookbook.cs public class Cookbook { private readonly ICollection<Recipe> recipes; public Cookbook(IEnumerable<Recipe> recipes) { this.recipes = new List<Recipe>(recipes); } public IEnumerable<Recipe> FindRecipies(params Ingredient[] ingredients) { return recipes.Where(r => r.Ingredients.Intersect(ingredients).Any()); } public void AddRecipe(Recipe recipe) { this.recipes.Add(recipe); } } // Recipe.cs public class Recipe { public readonly IEnumerable<Ingredient> Ingredients; public Recipe(IEnumerable<Ingredient> ingredients) { this.Ingredients = ingredients; } } // Ingredient.cs public class Ingredient { public readonly string Name; public Ingredient(string name) { this.Name = name; } } Nice and simple. But let’s not stop here. It’s time to take it a bit further. An opportunity for generalization Given the fact that we started working from a very concrete requirement, it’s only natural that the RandomIngredientsFromFixedSequence customization we came up at with encapsulates a behavior that is specific to the scenario at hand. However, if we take a closer look we might notice the following: The only part of the algorithm that is specific to the original scenario is the type of the objects being created. The rest can easily be applied whenever you want to create objects that are picked at random from a predefined pool. An opportunity for writing a general-purpose customization has just presented itself. We can’t let it slip. Let’s see what happens if we extract the Ingredient type into a generic argument and remove all references to the word “ingredient”: public class RandomFromFixedSequence<T> : ICustomization { private readonly Random randomizer = new Random(); private IEnumerable<T> sequence; public void Customize(IFixture fixture) { InitializeSequence(fixture); fixture.Register(PickRandomItemFromSequence); } private void InitializeSequence(IFixture fixture) { this.sequence = fixture.CreateMany<T>(); } private T PickRandomItemFromSequence() { var randomIndex = this.randomizer.Next(0, sequence.Count()); return sequence.ElementAt(randomIndex); } } Voilà. We just turned our scenario-specific customization into a pluggable algorithm that changes the way objects of any type are going to be generated by AutoFixture. In this case the algorithm will create items by picking them at random from a fixed sequence of T. The CookbookAutoDataAttribute can easily changed to use the general-purpose version of the customization by closing the generic argument with the Ingredient type: public class CookbookAutoDataAttribute : AutoDataAttribute { public CookbookAutoDataAttribute() : base(new Fixture().Customize( new RandomFromFixedSequence<Ingredient>()))) { } } The same is true if you’re using AutoFixture imperatively: var fixture = new Fixture(); fixture.Customize(new RandomFromFixedSequence<Ingredient>()); Wrapping up As I said before, customizations are a great way to set up test data for a specific scenario. Sometimes these configurations turn out to be useful in more than just one situation. When such opportunity arises, it’s often a good idea to separate out the parts that are specific to a particular context and turn them into parameters. This allows the customization to become a reusable strategy for controlling AutoFixture’s behavior across entire test suites. [Less]
Posted about 11 years ago
If you’ve been using AutoFixture in your tests for more than a while, chances are you’ve already come across the concept of customizations. If you’re not familiar with it, let me give you a quick introduction: A customization is a group of ... [More] settings that, when applied to a given Fixture object, control the way AutoFixture will create instances for the types requested through that Fixture. At this point you might find yourself feeling an irresistible urge to know everything there’s to know about customizations. If that’s the case, don’t worry. There are a few resources online where you learn more about them. For example, I wrote about how to take advantage of customizations to group together test data related to specific scenarios. In this post I’m going to talk about something different which, in a sense, is quite the opposite of that: how to write general-purpose customizations. A (user) story about cooking It’s hard to talk about test data without a bit of context. So, for the sake of this post, I thought we would pretend to be working on a somewhat realistic project. The system we’re going to build is an online catalogue of food recipies. The domain, at the very basic level, consists of three concepts: Cookbook Recipes Ingredients Now, let’s imagine that in our backlog of requirements we have one where the user wishes to be able to search for recepies that contain a specific set of ingredients. Or in other words: As a foodie, I want to know which recipes I can prepare with the ingredients I have, so that I can get the best value for my groceries. From the tests… As usual, we start out by translating the requirement at hand into a set of acceptance tests. In order do that, we need to tell AutoFixture how we’d like the test data for our domain model to be generated. For this particular scenario, we need every Ingredient created in the test fixture to be randomly chosen from a fixed pool of objects. That way we can ensure that all recepies in the cookbook will be made up of the same set of ingredients. Here’s how such a customization would look like: public class RandomIngredientsFromFixedSequence : ICustomization { private readonly Random randomizer = new Random(); private IEnumerable<Ingredient> sequence; public void Customize(IFixture fixture) { InitializeIngredientSequence(fixture); fixture.Register(PickRandomIngredientFromSequence); } private void InitializeIngredientSequence(IFixture fixture) { this.sequence = fixture.CreateMany<Ingredient>(); } private Ingredient PickRandomIngredientFromSequence() { var randomIndex = this.randomizer.Next(0, sequence.Count()); return sequence.ElementAt(randomIndex); } } Here we’re creating a pool of ingredients and telling AutoFixture to randomly pick one of those every time it needs to create an Ingredient object by using the Fixture.Register method. Since we’ll be using Xunit as our test runner, you can take advantage of the AutoFixture Data Theories to keep our tests succinct by using AutoFixture in a declarative fashion. In order to do so, we need to write an xUnit Data Theory attribute that tells AutoFixture to use our new customization: public class CookbookAutoDataAttribute : AutoDataAttribute { public CookbookAutoDataAttribute() : base(new Fixture().Customize( new RandomIngredientsFromFixedSequence()))) { } } If you prefer to use AutoFixture directly in your tests, the imperative equivalent of the above is: var fixture = new Fixture(); fixture.Customize(new RandomIngredientsFromFixedSequence()); At this point, we can finally start writing the acceptance tests to satisfy our original requirement: public class When_searching_for_recipies_by_ingredients { [Theory, CookbookAutoData] public void Should_only_return_recipes_with_a_specific_ingredient( Cookbook sut, Ingredient ingredient) { // When var recipes = sut.FindRecipies(ingredient); // Then Assert.True(recipes.All(r => r.Ingredients.Contains(ingredient))); } [Theory, CookbookAutoData] public void Should_include_new_recipes_with_a_specific_ingredient( Cookbook sut, Ingredient ingredient, Recipe recipeWithIngredient) { // Given sut.AddRecipe(recipeWithIngredient); // When var recipes = sut.FindRecipies(ingredient); // Then Assert.Contains(recipeWithIngredient, recipes); } } Notice that during these tests AutoFixture will have to create Ingredient objects in a couple of different ways: indirectly when constructing Recipe objects associated to a Cookbook directly when providing arguments for the test parameters As far as AutoFixture is concerned, it doesn’t really matter which code path leads to the creation of ingredients. The algorithm provided by the RandomIngredientsFromFixedSequence customization will apply in all situations. …to the implementation After a couple of Red-Green-Refactor cycles spawned from the above tests, it’s not completely unlikely that we might end up with some production code similar to this: // Cookbook.cs public class Cookbook { private readonly ICollection<Recipe> recipes; public Cookbook(IEnumerable<Recipe> recipes) { this.recipes = new List<Recipe>(recipes); } public IEnumerable<Recipe> FindRecipies(params Ingredient[] ingredients) { return recipes.Where(r => r.Ingredients.Intersect(ingredients).Any()); } public void AddRecipe(Recipe recipe) { this.recipes.Add(recipe); } } // Recipe.cs public class Recipe { public readonly IEnumerable<Ingredient> Ingredients; public Recipe(IEnumerable<Ingredient> ingredients) { this.Ingredients = ingredients; } } // Ingredient.cs public class Ingredient { public readonly string Name; public Ingredient(string name) { this.Name = name; } } Nice and simple. But let’s not stop here. It’s time to take it a bit further. An opportunity for generalization Given the fact that we started working from a very concrete requirement, it’s only natural that the RandomIngredientsFromFixedSequence customization we came up at with encapsulates a behavior that is specific to the scenario at hand. However, if we take a closer look we might notice the following: The only part of the algorithm that is specific to the original scenario is the type of the objects being created. The rest can easily be applied whenever you want to create objects that are picked at random from a predefined pool. An opportunity for writing a general-purpose customization has just presented itself. We can’t let it slip. Let’s see what happens if we extract the Ingredient type into a generic argument and remove all references to the word “ingredient”: public class RandomFromFixedSequence<T> : ICustomization { private readonly Random randomizer = new Random(); private IEnumerable<T> sequence; public void Customize(IFixture fixture) { InitializeSequence(fixture); fixture.Register(PickRandomItemFromSequence); } private void InitializeSequence(IFixture fixture) { this.sequence = fixture.CreateMany<T>(); } private T PickRandomItemFromSequence() { var randomIndex = this.randomizer.Next(0, sequence.Count()); return sequence.ElementAt(randomIndex); } } Voilà. We just turned our scenario-specific customization into a pluggable algorithm that changes the way objects of any type are going to be generated by AutoFixture. In this case the algorithm will create items by picking them at random from a fixed sequence of T. The CookbookAutoDataAttribute can easily changed to use the general-purpose version of the customization by closing the generic argument with the Ingredient type: public class CookbookAutoDataAttribute : AutoDataAttribute { public CookbookAutoDataAttribute() : base(new Fixture().Customize( new RandomFromFixedSequence<Ingredient>()))) { } } The same is true if you’re using AutoFixture imperatively: var fixture = new Fixture(); fixture.Customize(new RandomFromFixedSequence<Ingredient>()); Wrapping up As I said before, customizations are a great way to set up test data for a specific scenario. Sometimes these configurations turn out to be useful in more than just one situation. When such opportunity arises, it’s often a good idea to separate out the parts that are specific to a particular context and turn them into parameters. This allows the customization to become a reusable strategy for controlling AutoFixture’s behavior across entire test suites. [Less]
Posted about 11 years ago
If you’ve been using AutoFixture in your tests for more than a while, chances are you’ve already come across the concept of customizations. If you’re not familiar with it, let me give you a quick introduction: A customization is a group of ... [More] settings that, when applied to a given Fixture object, control the way AutoFixture will create instances for the types requested through that Fixture. At this point you might find yourself feeling an irresistible urge to know everything there’s to know about customizations. If that’s the case, don’t worry. There are a few resources online where you learn more about them. For example, I wrote about how to take advantage of customizations to group together test data related to specific scenarios. In this post I’m going to talk about something different which, in a sense, is quite the opposite of that: how to write general-purpose customizations. A (user) story about cooking It’s hard to talk about test data without a bit of context. So, for the sake of this post, I thought we would pretend to be working on a somewhat realistic project. The system we’re going to build is an online catalogue of food recipies. The domain, at the very basic level, consists of three concepts: Cookbook Recipes Ingredients Now, let’s imagine that in our backlog of requirements we have one where the user wishes to be able to search for recepies that contain a specific set of ingredients. Or in other words: As a foodie, I want to know which recipes I can prepare with the ingredients I have, so that I can get the best value for my groceries. From the tests… As usual, we start out by translating the requirement at hand into a set of acceptance tests. In order do that, we need to tell AutoFixture how we’d like the test data for our domain model to be generated. For this particular scenario, we need every Ingredient created in the test fixture to be randomly chosen from a fixed pool of objects. That way we can ensure that all recepies in the cookbook will be made up of the same set of ingredients. Here’s how such a customization would look like: public class RandomIngredientsFromFixedSequence : ICustomization { private readonly Random randomizer = new Random(); private IEnumerable<Ingredient> sequence; public void Customize(IFixture fixture) { InitializeIngredientSequence(fixture); fixture.Register(PickRandomIngredientFromSequence); } private void InitializeIngredientSequence(IFixture fixture) { this.sequence = fixture.CreateMany<Ingredient>(); } private Ingredient PickRandomIngredientFromSequence() { var randomIndex = this.randomizer.Next(0, sequence.Count()); return sequence.ElementAt(randomIndex); } } Here we’re creating a pool of ingredients and telling AutoFixture to randomly pick one of those every time it needs to create an Ingredient object by using the Fixture.Register method. Since we’ll be using Xunit as our test runner, you can take advantage of the AutoFixture Data Theories to keep our tests succinct by using AutoFixture in a declarative fashion. In order to do so, we need to write an xUnit Data Theory attribute that tells AutoFixture to use our new customization: public class CookbookAutoDataAttribute : AutoDataAttribute { public CookbookAutoDataAttribute() : base(new Fixture().Customize( new RandomIngredientsFromFixedSequence()))) { } } If you prefer to use AutoFixture directly in your tests, the imperative equivalent of the above is: var fixture = new Fixture(); fixture.Customize(new RandomIngredientsFromFixedSequence()); At this point, we can finally start writing the acceptance tests to satisfy our original requirement: public class When_searching_for_recipies_by_ingredients { [Theory, CookbookAutoData] public void Should_only_return_recipes_with_a_specific_ingredient( Cookbook sut, Ingredient ingredient) { // When var recipes = sut.FindRecipies(ingredient); // Then Assert.True(recipes.All(r => r.Ingredients.Contains(ingredient))); } [Theory, CookbookAutoData] public void Should_include_new_recipes_with_a_specific_ingredient( Cookbook sut, Ingredient ingredient, Recipe recipeWithIngredient) { // Given sut.AddRecipe(recipeWithIngredient); // When var recipes = sut.FindRecipies(ingredient); // Then Assert.Contains(recipeWithIngredient, recipes); } } Notice that during these tests AutoFixture will have to create Ingredient objects in a couple of different ways: indirectly when constructing Recipe objects associated to a Cookbook directly when providing arguments for the test parameters As far as AutoFixture is concerned, it doesn’t really matter which code path leads to the creation of ingredients. The algorithm provided by the RandomIngredientsFromFixedSequence customization will apply in all situations. …to the implementation After a couple of Red-Green-Refactor cycles spawned from the above tests, it’s not completely unlikely that we might end up with some production code similar to this: // Cookbook.cs public class Cookbook { private readonly ICollection<Recipe> recipes; public Cookbook(IEnumerable<Recipe> recipes) { this.recipes = new List<Recipe>(recipes); } public IEnumerable<Recipe> FindRecipies(params Ingredient[] ingredients) { return recipes.Where(r => r.Ingredients.Intersect(ingredients).Any()); } public void AddRecipe(Recipe recipe) { this.recipes.Add(recipe); } } // Recipe.cs public class Recipe { public readonly IEnumerable<Ingredient> Ingredients; public Recipe(IEnumerable<Ingredient> ingredients) { this.Ingredients = ingredients; } } // Ingredient.cs public class Ingredient { public readonly string Name; public Ingredient(string name) { this.Name = name; } } Nice and simple. But let’s not stop here. It’s time to take it a bit further. An opportunity for generalization Given the fact that we started working from a very concrete requirement, it’s only natural that the RandomIngredientsFromFixedSequence customization we came up at with encapsulates a behavior that is specific to the scenario at hand. However, if we take a closer look we might notice the following: The only part of the algorithm that is specific to the original scenario is the type of the objects being created. The rest can easily be applied whenever you want to create objects that are picked at random from a predefined pool. An opportunity for writing a general-purpose customization has just presented itself. We can’t let it slip. Let’s see what happens if we extract the Ingredient type into a generic argument and remove all references to the word “ingredient”: public class RandomFromFixedSequence<T> : ICustomization { private readonly Random randomizer = new Random(); private IEnumerable<T> sequence; public void Customize(IFixture fixture) { InitializeSequence(fixture); fixture.Register(PickRandomItemFromSequence); } private void InitializeSequence(IFixture fixture) { this.sequence = fixture.CreateMany<T>(); } private T PickRandomItemFromSequence() { var randomIndex = this.randomizer.Next(0, sequence.Count()); return sequence.ElementAt(randomIndex); } } Voilà. We just turned our scenario-specific customization into a pluggable algorithm that changes the way objects of any type are going to be generated by AutoFixture. In this case the algorithm will create items by picking them at random from a fixed sequence of T. The CookbookAutoDataAttribute can easily changed to use the general-purpose version of the customization by closing the generic argument with the Ingredient type: public class CookbookAutoDataAttribute : AutoDataAttribute { public CookbookAutoDataAttribute() : base(new Fixture().Customize( new RandomFromFixedSequence<Ingredient>()))) { } } The same is true if you’re using AutoFixture imperatively: var fixture = new Fixture(); fixture.Customize(new RandomFromFixedSequence<Ingredient>()); Wrapping up As I said before, customizations are a great way to set up test data for a specific scenario. Sometimes these configurations turn out to be useful in more than just one situation. When such opportunity arises, it’s often a good idea to separate out the parts that are specific to a particular context and turn them into parameters. This allows the customization to become a reusable strategy for controlling AutoFixture’s behavior across entire test suites. [Less]
Posted about 11 years ago by Mark Seemann
Announcing the general release of AutoFixture 3. AutoFixture 3 has been under way in a long time, but after about of a month of limited beta/CTP/whatever trial, I've decided to release it as the 'official' current version of AutoFixture. Since ... [More] AutoFixture uses Semantic Versioning, the shift from 2.16.2 to 3.0.0 (actually, 3.0.1) signifies breaking changes. While we've made an effort to make the impact of these breaking changes as light as possible, it's worth noting that it's probably not a good idea upgrading to AutoFixture 3 five minutes before you are heading out of the door for the weekend. Read more about what's new and what has changed in the release notes. Thank you to everyone who helped make this happen. There have been a lot of people contributing, providing feedback, asking intelligent questions, etc. but I particularly want to thank Nikos Baxevanis for all the work he's been putting into AutoFixture. Conversely, as is usual in such circumstances, all mistakes are my responsibility. What's new? When you read the release notes, you may find the amount of new features is quite unimpressive. This is because we've been continually releasing new features under the major version number of 2, in a sort of Continuous Delivery process. Because of the way Semantic Versioning works, breaking changes must be signaled by increasing the major version number, so while we could release new features as they became available, I thought it better to bundle up breaking changes into a bigger release; if not, we'd be looking at AutoFixture 7 or 8 now... And as I'm writing this, I notice that my installation of Chrome is on major version 25, so maybe it's just something I need to get over. Personal release notes One thing that the release notes don't explicitly mention, but I'd like to talk about a little is that AutoFixture 3 is running on an extensively rebuilt kernel. One of the visions I had for AutoFixture 3 was that the kernel structure should be immutable, and it should be as easy to take away functionality than it is to add custom functionality. Taking away functionality was really hard (or perhaps impossible) in AutoFixture 2, and that put a constraint on what you could do with AutoFixture. It also put a constraint on how opinionated its defaults could be. The AutoFixture 3 kernel makes it possible to take away functionality, as well as add new functionality. At the moment, you have to understand the underlying kernel to figure out how to do that, but in the future I plan to surface an API for that as well. In any case, I find it interesting that using real SOLID principles, I was able to develop the new kernel in parallel with the version 2 kernel. Partly because I was very conscious of not introducing breaking changes, but also because I follow the Open/Closed Principle, I rarely had to touch existing code, but could build the new parts of the kernel in parallel. Even more interestingly, I think, is the fact that once that work was done, replacing the kernel turned out to be a point release. This happened late November 2012 - more than three months ago. If you've been using AutoFixture 2.14.1 or a more recent version, you've already been using the AutoFixture 3 kernel for some time. The reason I find this interesting is that sometimes casual readers of my blog express skepticism over whether the principles I talk about can be applied in 'realistic' settings. According to Ohloh, AutoFixture has a total of 197,935 lines of code, and I consider that a fair sized code base. I practice what I preach. QED. This blog is totally free, but if you like it, please buy me a cup of coffee. [Less]