Skip to content

Commit

Permalink
Add optional instance data to AddProperty method
Browse files Browse the repository at this point in the history
  • Loading branch information
cwinland committed Jul 30, 2024
1 parent abb3e9b commit 30bde3a
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 8 deletions.
29 changes: 21 additions & 8 deletions FastMoq.Core/Mocker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,9 @@ public MockModel<T> AddMock<T>(Mock<T> mock, bool overwrite, bool nonPublic = fa
/// <typeparam name="T"></typeparam>
/// <param name="obj">The object.</param>
/// <returns>T.</returns>
public T? AddProperties<T>(T obj)
public T? AddProperties<T>(T obj, params KeyValuePair<string, object>[] data)
{
var o = AddProperties(typeof(T), obj);
var o = AddProperties(typeof(T), obj, data);
return o is not null ? (T) o : default;
}

Expand All @@ -241,8 +241,8 @@ public MockModel<T> AddMock<T>(Mock<T> mock, bool overwrite, bool nonPublic = fa
/// </summary>
/// <param name="type">The type.</param>
/// <param name="obj">The object.</param>
/// <returns>object.</returns>
public object? AddProperties(Type type, object? obj)
/// <param name="data">Data to insert. <see cref="KeyValuePair" /> should be property name and property value.</param>
public object? AddProperties(Type type, object? obj, params KeyValuePair<string, object>[] data)
{
ArgumentNullException.ThrowIfNull(type);

Expand All @@ -258,7 +258,7 @@ public MockModel<T> AddMock<T>(Mock<T> mock, bool overwrite, bool nonPublic = fa

foreach (var writableProperty in writableProperties)
{
AddProperty(obj, writableProperty);
AddProperty(obj, writableProperty, data);
}
}
finally
Expand Down Expand Up @@ -1335,13 +1335,26 @@ internal MockModel AddMock(Mock mock, Type type, bool overwrite = false, bool no
/// <exception cref="System.ArgumentNullException" />
public void CallMethod(Delegate method, params object?[]? args) => CallMethod<object>(method, args);

internal void AddProperty(object? obj, PropertyInfo writableProperty)
internal void AddProperty(object? obj, PropertyInfo writableProperty, params KeyValuePair<string, object>[] data)
{
try
{
if (writableProperty.GetValue(obj) is null && !creatingTypeList.Contains(writableProperty.PropertyType))
var value = writableProperty.GetValue(obj);

var canWrite = !creatingTypeList.Contains(writableProperty.PropertyType) &&
(
data.Any(x => x.Key.Contains(writableProperty.Name, StringComparison.OrdinalIgnoreCase)) ||
value is null ||
writableProperty.PropertyType.IsValueType && string.IsNullOrEmpty(value.ToString()) ||
(writableProperty.PropertyType.Name.Equals("String", StringComparison.OrdinalIgnoreCase) &&
string.IsNullOrEmpty(value.ToString()))
);
if (canWrite)
{
writableProperty.SetValue(obj, GetObject(writableProperty.PropertyType));
value = data.Any(x => x.Key.Contains(writableProperty.Name, StringComparison.OrdinalIgnoreCase))
? data.First(x => x.Key.Contains(writableProperty.Name, StringComparison.OrdinalIgnoreCase)).Value
: GetObject(writableProperty.PropertyType);
writableProperty.SetValue(obj, value);
}
}
catch (Exception ex)
Expand Down
43 changes: 43 additions & 0 deletions FastMoq.Tests/MocksTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,49 @@ public void VerifyLogger_ShouldThrow_WhenNotMatches()
Assert.Throws<MockException>(() => mLogger.VerifyLogger(LogLevel.Error, "test", new AmbiguousImplementationException("Test Exception"), 0)); // Wrong eventId.
}

[Fact]
public void AddProperties_WritableProperty_ShouldHaveValue()
{
var obj = Mocks.GetObject<SubscriptionData>();
Component.AddProperties(obj, new KeyValuePair<string, object>("DisplayName", "TestDisplay"), new KeyValuePair<string, object>("SubscriptionId", "testSub"), new KeyValuePair<string, object>("tenantId", Guid.NewGuid()));
obj.DisplayName.Should().NotBeNullOrEmpty();
obj.SubscriptionId.Should().BeNullOrEmpty();
obj.TenantId.Should().BeNull();
}

[Fact]
public void AddProperties_WritableProperty_ShouldHaveValue2()
{
var mock = Mocks.GetMock<SubscriptionData>();
var obj = mock.Object;
Component.AddProperties(obj, new KeyValuePair<string, object>("DisplayName", "TestDisplay"), new KeyValuePair<string, object>("SubscriptionId", "testSub"), new KeyValuePair<string, object>("tenantId", Guid.NewGuid()));
obj.DisplayName.Should().NotBeNullOrEmpty();
obj.SubscriptionId.Should().BeNullOrEmpty();
obj.TenantId.Should().BeNull();
}

[Fact]
public void AddProperties_WritableProperty_WithAddType_ShouldHaveValues2()
{
Mocks.AddType(_ => "Display Name Test");
var mock = Mocks.GetMock<SubscriptionData>();
var obj = mock.Object;
Component.AddProperties(obj, new KeyValuePair<string, object>("DisplayName", "TestDisplay"));
obj.DisplayName.Should().Be("TestDisplay");
obj.SubscriptionId.Should().Be("Display Name Test");
obj.TenantId.Should().BeNull();
}

//[Fact]
//public void AddProperties_WritableProperty_WithAddType_ShouldHaveValues3()
//{
// Mocks.AddType(x => "Display Name Test");
// var mock = Mocks.GetMock<SubscriptionData>();
// var obj = mock.Object;
// obj.DisplayName.Should().Be("TestDisplay");
// obj.SubscriptionId.Should().Be("Display Name Test");
// obj.TenantId.Should().BeNull();
//}
private static void LogException(Exception ex, ILogger log, string customMessage = "", [CallerMemberName] string caller = "")
{
log.LogError("[{caller}] - {customMessage}{errorMessage}", caller, $"{customMessage} ", ex.Message);
Expand Down
35 changes: 35 additions & 0 deletions FastMoq.Tests/TestClasses/SubscriptionData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;

namespace FastMoq.Tests.TestClasses
{
public class SubscriptionData
{
internal SubscriptionData()
{
}

internal SubscriptionData(string subscriptionId, string displayName, Guid? tenantId, string authorizationSource, IReadOnlyList<Guid> managedByTenants, IReadOnlyDictionary<string, string> tags)
{
SubscriptionId = subscriptionId;
DisplayName = displayName;
TenantId = tenantId;
AuthorizationSource = authorizationSource;
ManagedByTenants = managedByTenants;
Tags = tags;
}
/// <summary> The subscription ID. </summary>
public string SubscriptionId { get; }
/// <summary> The subscription display name. </summary>
public string DisplayName { get; set; }
/// <summary> The subscription tenant ID. </summary>
public Guid? TenantId { get; }
/// <summary> The subscription state. Possible values are Enabled, Warned, PastDue, Disabled, and Deleted. </summary>
/// <summary> The authorization source of the request. Valid values are one or more combinations of Legacy, RoleBased, Bypassed, Direct and Management. For example, 'Legacy, RoleBased'. </summary>
public string AuthorizationSource { get; }
/// <summary> An array containing the tenants managing the subscription. </summary>
public IReadOnlyList<Guid> ManagedByTenants { get; }
/// <summary> The tags attached to the subscription. </summary>
public IReadOnlyDictionary<string, string> Tags { get; }
}
}

0 comments on commit 30bde3a

Please sign in to comment.