diff --git a/Source/Mockolate/Setup/Interfaces.PropertySetup.cs b/Source/Mockolate/Setup/Interfaces.PropertySetup.cs index ba43a19b..a54f9908 100644 --- a/Source/Mockolate/Setup/Interfaces.PropertySetup.cs +++ b/Source/Mockolate/Setup/Interfaces.PropertySetup.cs @@ -118,6 +118,14 @@ public interface IPropertySetup /// IPropertySetup CallingBaseClass(bool callBaseClass = true); + /// + /// Register the property to have a setup without a specific value. + /// + /// + /// This is necessary when the mock uses . + /// + IPropertySetup Register(); + /// /// Initializes the property with the given . /// diff --git a/Source/Mockolate/Setup/PropertySetup.cs b/Source/Mockolate/Setup/PropertySetup.cs index 8f3d4661..74216203 100644 --- a/Source/Mockolate/Setup/PropertySetup.cs +++ b/Source/Mockolate/Setup/PropertySetup.cs @@ -298,6 +298,10 @@ public IPropertySetup CallingBaseClass(bool callBaseClass = true) return this; } + /// + public IPropertySetup Register() + => this; + /// public IPropertySetup InitializeWith(T value) { diff --git a/Tests/Mockolate.Api.Tests/Expected/Mockolate_net10.0.txt b/Tests/Mockolate.Api.Tests/Expected/Mockolate_net10.0.txt index 8e73ee3d..1ce2740d 100644 --- a/Tests/Mockolate.Api.Tests/Expected/Mockolate_net10.0.txt +++ b/Tests/Mockolate.Api.Tests/Expected/Mockolate_net10.0.txt @@ -888,6 +888,7 @@ namespace Mockolate.Setup Mockolate.Setup.IPropertySetterSetup OnSet { get; } Mockolate.Setup.IPropertySetup CallingBaseClass(bool callBaseClass = true); Mockolate.Setup.IPropertySetup InitializeWith(T value); + Mockolate.Setup.IPropertySetup Register(); Mockolate.Setup.IPropertySetupReturnBuilder Returns(System.Func callback); Mockolate.Setup.IPropertySetupReturnBuilder Returns(System.Func callback); Mockolate.Setup.IPropertySetupReturnBuilder Returns(T returnValue); @@ -1405,6 +1406,7 @@ namespace Mockolate.Setup protected override TResult InvokeGetter(Mockolate.MockBehavior behavior, System.Func defaultValueGenerator) { } protected override void InvokeSetter(object? value, Mockolate.MockBehavior behavior) { } protected override bool Matches(Mockolate.Interactions.PropertyAccess propertyAccess) { } + public Mockolate.Setup.IPropertySetup Register() { } public Mockolate.Setup.IPropertySetupReturnBuilder Returns(System.Func callback) { } public Mockolate.Setup.IPropertySetupReturnBuilder Returns(System.Func callback) { } public Mockolate.Setup.IPropertySetupReturnBuilder Returns(T returnValue) { } diff --git a/Tests/Mockolate.Api.Tests/Expected/Mockolate_net8.0.txt b/Tests/Mockolate.Api.Tests/Expected/Mockolate_net8.0.txt index b8b80164..55efb907 100644 --- a/Tests/Mockolate.Api.Tests/Expected/Mockolate_net8.0.txt +++ b/Tests/Mockolate.Api.Tests/Expected/Mockolate_net8.0.txt @@ -887,6 +887,7 @@ namespace Mockolate.Setup Mockolate.Setup.IPropertySetterSetup OnSet { get; } Mockolate.Setup.IPropertySetup CallingBaseClass(bool callBaseClass = true); Mockolate.Setup.IPropertySetup InitializeWith(T value); + Mockolate.Setup.IPropertySetup Register(); Mockolate.Setup.IPropertySetupReturnBuilder Returns(System.Func callback); Mockolate.Setup.IPropertySetupReturnBuilder Returns(System.Func callback); Mockolate.Setup.IPropertySetupReturnBuilder Returns(T returnValue); @@ -1404,6 +1405,7 @@ namespace Mockolate.Setup protected override TResult InvokeGetter(Mockolate.MockBehavior behavior, System.Func defaultValueGenerator) { } protected override void InvokeSetter(object? value, Mockolate.MockBehavior behavior) { } protected override bool Matches(Mockolate.Interactions.PropertyAccess propertyAccess) { } + public Mockolate.Setup.IPropertySetup Register() { } public Mockolate.Setup.IPropertySetupReturnBuilder Returns(System.Func callback) { } public Mockolate.Setup.IPropertySetupReturnBuilder Returns(System.Func callback) { } public Mockolate.Setup.IPropertySetupReturnBuilder Returns(T returnValue) { } diff --git a/Tests/Mockolate.Api.Tests/Expected/Mockolate_netstandard2.0.txt b/Tests/Mockolate.Api.Tests/Expected/Mockolate_netstandard2.0.txt index ae51ca30..22826a84 100644 --- a/Tests/Mockolate.Api.Tests/Expected/Mockolate_netstandard2.0.txt +++ b/Tests/Mockolate.Api.Tests/Expected/Mockolate_netstandard2.0.txt @@ -864,6 +864,7 @@ namespace Mockolate.Setup Mockolate.Setup.IPropertySetterSetup OnSet { get; } Mockolate.Setup.IPropertySetup CallingBaseClass(bool callBaseClass = true); Mockolate.Setup.IPropertySetup InitializeWith(T value); + Mockolate.Setup.IPropertySetup Register(); Mockolate.Setup.IPropertySetupReturnBuilder Returns(System.Func callback); Mockolate.Setup.IPropertySetupReturnBuilder Returns(System.Func callback); Mockolate.Setup.IPropertySetupReturnBuilder Returns(T returnValue); @@ -1381,6 +1382,7 @@ namespace Mockolate.Setup protected override TResult InvokeGetter(Mockolate.MockBehavior behavior, System.Func defaultValueGenerator) { } protected override void InvokeSetter(object? value, Mockolate.MockBehavior behavior) { } protected override bool Matches(Mockolate.Interactions.PropertyAccess propertyAccess) { } + public Mockolate.Setup.IPropertySetup Register() { } public Mockolate.Setup.IPropertySetupReturnBuilder Returns(System.Func callback) { } public Mockolate.Setup.IPropertySetupReturnBuilder Returns(System.Func callback) { } public Mockolate.Setup.IPropertySetupReturnBuilder Returns(T returnValue) { } diff --git a/Tests/Mockolate.Tests/MockProperties/SetupPropertyTests.RegisterTests.cs b/Tests/Mockolate.Tests/MockProperties/SetupPropertyTests.RegisterTests.cs new file mode 100644 index 00000000..aefd4581 --- /dev/null +++ b/Tests/Mockolate.Tests/MockProperties/SetupPropertyTests.RegisterTests.cs @@ -0,0 +1,39 @@ +using Mockolate.Exceptions; + +namespace Mockolate.Tests.MockProperties; + +public sealed partial class SetupPropertyTests +{ + public sealed class RegisterTests + { + [Fact] + public async Task AccessWithoutSetup_ShouldThrowMockNotSetupException() + { + IPropertyService mock = Mock.Create(MockBehavior.Default.ThrowingWhenNotSetup()); + + void Act() + { + mock.MyStringProperty = "1"; + } + + await That(Act).Throws() + .WithMessage( + "The property 'Mockolate.Tests.MockProperties.SetupPropertyTests.IPropertyService.MyStringProperty' was accessed without prior setup."); + } + + [Fact] + public async Task RegisterBeforeAccess_ShouldNotThrowAndReturnDefaultValue() + { + IPropertyService mock = Mock.Create(MockBehavior.Default.ThrowingWhenNotSetup()); + + mock.SetupMock.Property.MyStringProperty.Register(); + + string? initialResult = mock.MyStringProperty; + mock.MyStringProperty = "foo"; + string? otherResult = mock.MyStringProperty; + + await That(initialResult).IsEmpty(); + await That(otherResult).IsEqualTo("foo"); + } + } +}