diff --git a/Source/Mockolate/DefaultValueFactory.cs b/Source/Mockolate/DefaultValueFactory.cs
new file mode 100644
index 00000000..c63290aa
--- /dev/null
+++ b/Source/Mockolate/DefaultValueFactory.cs
@@ -0,0 +1,42 @@
+using System;
+
+namespace Mockolate;
+
+///
+/// Defines a mechanism for generating default values.
+///
+public class DefaultValueFactory
+{
+ private readonly Func? _generator;
+ private readonly Func? _predicate;
+
+ ///
+ /// This constructor is protected to allow inheritance.
+ ///
+ // ReSharper disable once UnusedMember.Global
+ protected DefaultValueFactory()
+ {
+ }
+
+ ///
+ /// Creates a new default value factory for types that match the given .
+ ///
+ public DefaultValueFactory(Func predicate, Func generator)
+ {
+ _predicate = predicate;
+ _generator = generator;
+ }
+
+ ///
+ /// Checks if the factory can generate a value for the specified .
+ ///
+ public virtual bool CanGenerateValue(Type type)
+ => _predicate?.Invoke(type) ?? false;
+
+ ///
+ /// Generates a default value of the specified , with
+ /// the for context.
+ ///
+ public virtual object? GenerateValue(Type type, params object?[] parameters)
+ => _generator?.Invoke(type, parameters);
+}
diff --git a/Source/Mockolate/MockBehavior.cs b/Source/Mockolate/MockBehavior.cs
index ea6192ac..f5cf536b 100644
--- a/Source/Mockolate/MockBehavior.cs
+++ b/Source/Mockolate/MockBehavior.cs
@@ -136,6 +136,18 @@ public MockBehavior UseConstructorParametersFor(params object?[] parameters)
return behavior;
}
+ ///
+ /// Uses the given to create default values for supported types.
+ ///
+ public MockBehavior WithDefaultValueFor(params DefaultValueFactory[] defaultValueFactories)
+ {
+ MockBehavior behavior = this with
+ {
+ DefaultValue = new DefaultValueGeneratorWithFactories(DefaultValue, defaultValueFactories),
+ };
+ return behavior;
+ }
+
private interface IInitializer;
private interface IInitializer : IInitializer
@@ -169,4 +181,21 @@ public Action>[] GetSetups()
return setups.Select(a => new Action>(s => a(index, s))).ToArray();
}
}
+
+ private sealed class DefaultValueGeneratorWithFactories(
+ IDefaultValueGenerator inner,
+ DefaultValueFactory[] factories)
+ : IDefaultValueGenerator
+ {
+ public object? GenerateValue(Type type, params object?[] parameters)
+ {
+ DefaultValueFactory? factory = factories.FirstOrDefault(f => f.CanGenerateValue(type));
+ if (factory is not null)
+ {
+ return factory.GenerateValue(type, parameters);
+ }
+
+ return inner.GenerateValue(type, parameters);
+ }
+ }
}
diff --git a/Source/Mockolate/MockBehaviorExtensions.cs b/Source/Mockolate/MockBehaviorExtensions.cs
index b434b654..d01a6f17 100644
--- a/Source/Mockolate/MockBehaviorExtensions.cs
+++ b/Source/Mockolate/MockBehaviorExtensions.cs
@@ -1,3 +1,5 @@
+using System;
+
namespace Mockolate;
///
@@ -34,5 +36,13 @@ public MockBehavior ThrowingWhenNotSetup(bool throwWhenNotSetup = true)
{
ThrowWhenNotSetup = throwWhenNotSetup,
};
+
+ ///
+ /// Uses the given to create default values for .
+ ///
+ public MockBehavior WithDefaultValueFor(Func factory)
+ => mockBehavior.WithDefaultValueFor(new DefaultValueFactory(
+ t => t == typeof(T),
+ (_, _) => factory()));
}
}
diff --git a/Tests/Mockolate.Api.Tests/Expected/Mockolate_net10.0.txt b/Tests/Mockolate.Api.Tests/Expected/Mockolate_net10.0.txt
index 65bf0858..a18a1ac2 100644
--- a/Tests/Mockolate.Api.Tests/Expected/Mockolate_net10.0.txt
+++ b/Tests/Mockolate.Api.Tests/Expected/Mockolate_net10.0.txt
@@ -13,6 +13,13 @@ namespace Mockolate
public object?[] Parameters { get; init; }
}
}
+ public class DefaultValueFactory
+ {
+ protected DefaultValueFactory() { }
+ public DefaultValueFactory(System.Func predicate, System.Func generator) { }
+ public virtual bool CanGenerateValue(System.Type type) { }
+ public virtual object? GenerateValue(System.Type type, params object?[] parameters) { }
+ }
public interface IDefaultValueGenerator
{
object? GenerateValue(System.Type type, params object?[] parameters);
@@ -90,6 +97,7 @@ namespace Mockolate
public Mockolate.MockBehavior Initialize(params System.Action>[] setups) { }
public Mockolate.MockBehavior UseConstructorParametersFor(System.Func