> ## Content Index
> Fetch the complete content index at: https://blog.davidkrammer.de/llms.txt
> Use this file to discover other available public pages before exploring further.

# The ObjectGodmother pattern - Solving the test data dependency problem
- URL: https://blog.davidkrammer.de/the-objectgodmother-pattern-solving-the-test-data-dependency-problem/
- Published: 2026-07-15T18:09:01.000Z
- Updated: 2026-07-23T07:58:08.000Z
- Author: David Krammer
- Tags: Tech, .net, unit tests, c#

For most of my career, I've been working in domain-heavy teams, meaning: one of our main tasks was to understand what the business department is doing, why they are doing it, and to build digital tools around it to facilitate their work.

Almost all the time, we were using some soft of custom-DDD flavor. To have the domain logic in a central, gatekeeping place, put it as deep into the model as possible. But this domain logic needs to be tested and tested well. After all, it's the core of the application - if you don't test the domain logic, what *do* you test?

(I'm not going into the E2E vs integration vs unit test discussion now. I'm focusing on unit tests, but depending on how you set up your tests, you might be able to apply the same concepts to E2E and integration tests as well.)

Setting up test data for domain tests can be a pain, especially the bigger and more complex your domain becomes. The holy trinity of **ObjectBuilder** pattern, **ObjectMother** pattern and [**AutoFixture**](https://github.com/AutoFixture/AutoFixture) (a .net package for random data generation) has been a lifesaver so many times in the past. With these, we can concentrate on the main data setup in a test and let the rest be randomly generated. Let's at first define the patterns and then look at a (simplified) real-world example.

- [ObjectBuilder](https://refactoring.guru/design-patterns/builder) pattern: An object builder focuses on **building/configuring a single object**, enabling us to set up an object just the way we need it to be for the test, without any logic applied. The object builder is fully indifferent to what you pass into it and whether it is valid (from a domain perspective) or not.
- [ObjectMother](https://martinfowler.com/bliki/ObjectMother.html) patter: The object mother **puts domain logic around the object builder**. Its methods represent different (high-level) **use-cases** that pre-configure an object builder instance with data for this respective use-case. It then returns the builder for further configuring this pre-defined use-case inside a specific test.

## Problem Scenario

I'm maintaining (as much as possible) a self-hostable [shopping list app](https://github.com/Velociraptor45/Xipona). It has an aggregate root `Item`. An item has a list of `ItemTypes` and every `ItemType` has a list of `Availabilies` (for every existing store up to one availability) that reference a `Store` by Id, define the type's price and the `Section` (referenced by Id as well) where it is located inside the store. Meaning, you e.g. have an item "Marmalade" with types "Strawberry" and "Peach" - the types representing different available flavors. "Strawberry" might be available in two stores (thus, has two availabilities), whereas "Peach" in only available in one of those stores (having only one availability).

You might now already recognize that we need another aggregate root for that to work: `Store`. A store has a name and a list of `Sections` (aka aisles).

In the end, leaving us with these classes (I'll make them records without logic for brevity and added an `IsDeleted` flag to the `Store` to indicate whether it is soft-deleted or not - you'll see later why we need that):

```csharp
public record Item(string Name, IReadOnlyList<ItemType> ItemTypes);
public record ItemType(string Name, IReadOnlyList<Availability> Availabilities);
public record Availability(StoreId StoreId, decimal Price, SectionId SectionId);
public record Store(StoreId Id, IReadOnlyList<Section> Sections, string Name, bool IsDeleted);
public record Section(SectionId Id, string Name);
```

An object builder for `Item` could look like this (Under usage of my [TestCodeGenerator](https://github.com/Velociraptor45/TestCodeGenerator), I can auto-generate these classes as they are a pain to write on your own. The [DomainTestBuilderBase](https://github.com/Velociraptor45/Xipona/blob/develop/Api/Xipona.Api.Domain.TestKit/Common/DomainTestBuilderBase.cs) base class is custom and abstracts away all the underlying AutoFixture configuration):

```csharp
public class ItemBuilder : DomainTestBuilderBase<Item>
{
    public ItemBuilder WithName(string name)
    {
        FillConstructorWith(nameof(name), name);
        return this;
    }
    
    public ItemBuilder WithItemTypes(IReadOnlyList&lt;ItemType&gt; itemTypes)
    {
        FillConstructorWith(nameof(itemTypes), itemTypes);
        return this;
    }
}
```

(What AutoFixture does, is populate the ctor parameters with the values that you pass into the `.With...` methods. All other parameters will be randomly filled.)

An object mother might look like this, generating a test case where the `Item` has two `ItemTypes` at the same store:

```csharp
public static class ItemMother
{
    public static ItemBuilder TwoTypesAtSameStore()
    {
        var storeId = StoreId.New;
        var av1 = new AvailabilityBuilder().WithStoreId(storeId).Create();
        var av2 = new AvailabilityBuilder().WithStoreId(storeId).Create();
        List<ItemType> types =
        [
            new ItemTypeBuilder().WithAvailabilities([av1]).Create(),
            new ItemTypeBuilder().WithAvailabilities([av2]).Create()
        ];
        return new ItemBuilder().WithItemTypes(types);
    }
}
```

Notice that it's static, so in the test code you can do `var item = ItemMother.TwoTypesAtSameStore().Create()`, without having to initialize a mother object.

I'm sure you can imagine what this looks like for the other classes, so I'll skip their code here for brevity.

## The Gap

Cool. Removing a lot of code from the test methods. But now we have a unit test where we want to test a specific `Item` setup. However, for this test to work, we need a not-deleted `Store` object that corresponds to the IDs in the `Item` object. This can be achieved with the `StoreBuilder`. But it's laborious to do and adds a lot of code to the test that does not add anything to the understanding of the test itself. We need a valid `Store` object, but get noise instead:

```csharp
var item = ItemMother.TwoTypesAtSameStore().Create();
var av1 = item.ItemTypes[0].Availabilities[0];
var av2 = item.ItemTypes[1].Availabilities[0];
List<Section> sections =
[
    // make sure the availabilities' SectionIds exist
    new SectionBuilder().WithId(av1.SectionId).Create(),
    new SectionBuilder().WithId(av2.SectionId).Create()
];
// make sure the availabilities' StoreId exist & store is not deleted
var store = new StoreBuilder().WithId(av1.StoreId)
    .WithSections(sections).WithIsDeleted(false).Create();
```

We add 9 lines of code, while we only wanted a valid `Store` object.

This is the gap that the ObjectGodmother pattern solves. It is responsible for **providing a valid foundation for an object corresponding to another one**. Let's build one for our store:

```csharp
public class StoreGodmother
{
    private Availability[]? _availabilities;
    public StoreGodmother For(params Availability[] availabilities)
    {
        _availabilities = availabilities;
        return this;
    }
    
    public StoreBuilder GetFoundation()
    {
        if(_availabilities is null) return new StoreBuilder();
        
        var storeIds = _availabilities.Select(av =&gt; av.StoreId).Distinct().ToList();
        // all availabilities must be for the same store as we're only building one store
        if(storeIds.Count &gt; 1)
            throw new ArgumentException("All availabilities must have the same StoreId");
    
        var sectionIds = _availabilities.Select(av =&gt; av.SectionId).Distinct().ToList();
        var sections = sectionIds.Select(sectionId =&gt; 
            new SectionBuilder().WithId(sectionId).Create()).ToList();
        
        return new StoreBuilder().WithId(storeIds[0]).WithSections(sections);
    }
}
```

You might now be tempted to call the `GetFoundation` method directly and turn the returned builder into a `Store` object:

```csharp
var item = ItemMother.TwoTypesAtSameStore().Create();
var avs = item.ItemTypes.SelectMany(t => t.Availabilities).ToList();
var store = new StoreGodmother().For(avs).GetFoundation().Create();
```

But the Godmother pattern itself **does not ensure a valid object for the test**! That's not what it's responsible for. If you compare the previous setup with this one, you'll notice that the Godmother does not set the `WithIsDeleted(false)` to ensure that the store is not marked as soft-deleted.

So, let's combine it with the ObjectMother pattern:

```csharp
public static class StoreMother
{
    public static StoreBuilder Active(StoreGodmother? gm = null)
    {
        return (gm?.GetFoundation() ?? new StoreBuilder())
            .WithIsDeleted(false);
    }
}
```

```csharp
var item = ItemMother.TwoTypesAtSameStore().Create();
var avs = item.ItemTypes.SelectMany(t => t.Availabilities).ToList();
var store = StoreMother.Active(new StoreGodmother().For(avs)).Create();
```

We pass the godmother into the mother's method and let the method get the foundation. Making the parameter by default `null` enables us to still call it without a godmother, like `var store = StoreMother.Active().Create()`, in case we only need an active store and don't care about the rest.

This makes it possible to outsource the logic that is merely responsible to construct valid references to another object into the Godmother class and clean up our unit test. This might not look like much, but having worked in highly complex scenarios with huge domain models, code like this can escalate really quickly - only for ensuring valid object references that don't add any meaning to the test.

## Design Considerations

While you are welcome to implement the pattern in your own way, I'd like to explain some of the considerations behind my implementation.

1. Why the `.For(...)` method? Why not pass the `Availability` array into the godmother's ctor?  
While that is technically possible and should suffice in most cases, I've migrated only small parts of my code to this pattern, and I'm already seeing that a godmother needs to handle different reference types at the same time. Extending the example, I have another type of availability that sits on the `Item` directly and the godmother needs to be able to handle either one of the two types, or both at the same time and create a valid store foundation. Thus, I found it easier to add another `.For(params OtherAvailability[] avs)` to the godmother and chain them at will, depending on my needs.
2. Why's the godmother passed into the mother's method, not the ctor?  
I like my mothers static in order to save the code of a ctor call because you can't chain multiple mother methods anyway (they return a builder, not a mother) and thus it makes little difference to the internal code if you store the godmother in a field or pass it into the method directly.

> \> Where's the name coming from?  
> I recently read "Nettle and Bone" by T. Kingfisher and in it, godmothers are magic-capable women who bless a child upon birth to define the foundation of its life. And I found that very fitting, needing a name for something that lays the foundation of an object's configuration before it's further configured (raised?) by a mother.

## Conclusion

When it comes to domain data generation, especially in DDD-like scenarios, the ObjectGodmother pattern can help to further reduce code in unit tests by outsourcing the setup of valid object references. To again give a short overview, this is what the three patterns are responsible for:

- ObjectBuilder: Configure one object, no logical checks
- ObjectMother: Pre-configure one object for a certain use-case
- ObjectGodmother: Pre-configure one object to ensure valid references to another object