Skip to content

Commit

Permalink
chore(tunittest): add fluentbogus unit tests (#15)
Browse files Browse the repository at this point in the history
Add FluentBogus unit tests
Fixes #6

---------

Co-authored-by: Bruno DUVAL <bruno.duval@datatunning.com>
  • Loading branch information
duvalbruno and Bruno DUVAL authored Dec 12, 2023
1 parent 3e768d6 commit 24bd68e
Show file tree
Hide file tree
Showing 25 changed files with 966 additions and 311 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<SignAssembly>True</SignAssembly>
<DelaySign>True</DelaySign>
<AssemblyOriginatorKeyFile>..\nineteensevenfour-public.snk</AssemblyOriginatorKeyFile>
<ApplicationIcon>..\NineteenFourSeven_logo.ico</ApplicationIcon>
</PropertyGroup>

Expand Down
74 changes: 70 additions & 4 deletions NineteenSevenFour.Testing.Core/Extension/FluentExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,86 @@ namespace NineteenSevenFour.Testing.Core.Extension;
[EditorBrowsable(EditorBrowsableState.Never)]
public static class FluentExpression
{
#region Member NameFor<>
/// <summary>
/// Members the name for.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TProp">The type of the property.</typeparam>
/// <param name="expression">The expression.</param>
/// <returns></returns>
public static string? MemberNameFor<T, TProp>(Expression<Func<T, TProp>> expression)
{
Expression body = expression.Body;
return body.AsMemberExpression()?.Member.Name;
}

/// <summary>
/// Members the name for.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="expression">The expression.</param>
/// <returns></returns>
public static string? MemberNameFor<T>(Expression<Func<T, object>> expression)
{
Expression body = expression.Body;
return body.AsMemberExpression()?.Member?.Name;
}

/// <summary>
/// Members the name for.
/// </summary>
/// <param name="expression">The expression.</param>
/// <returns></returns>
public static string? MemberNameFor(Expression<Func<object>> expression)
{
Expression body = expression.Body;
return body.AsMemberExpression()?.Member?.Name;
}
#endregion

#region Memeber TypeFor<>
/// <summary>
/// Members the type for.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TProp">The type of the property.</typeparam>
/// <param name="expression">The expression.</param>
/// <returns></returns>
public static Type? MemberTypeFor<T, TProp>(Expression<Func<T, TProp>> expression) => expression.Body.MemberTypeFor();

/// <summary>
/// Members the type for.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="expression">The expression.</param>
/// <returns></returns>
public static Type? MemberTypeFor<T>(Expression<Func<T, object>> expression) => expression.Body.MemberTypeFor();

/// <summary>
/// Members the type for.
/// </summary>
/// <param name="expression">The expression.</param>
/// <returns></returns>
public static Type? MemberTypeFor(Expression<Func<object>> expression) => expression.Body.MemberTypeFor();

/// <summary>
/// Members the type for.
/// </summary>
/// <param name="expression">The expression.</param>
/// <returns></returns>
private static Type? MemberTypeFor(this Expression expression)
{
var memberExp = expression?.AsMemberExpression();
return memberExp?.Type?.IsGenericType == true
? ((PropertyInfo)memberExp.Member).PropertyType.GetGenericArguments()[0]
: memberExp?.Type;
}
#endregion

/// <summary>
/// Ensures the member exists.
/// </summary>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
/// <param name="propNameOrField">The property name or field.</param>
/// <param name="exceptionMessage">The exception message.</param>
/// <exception cref="System.ArgumentException"></exception>
public static void EnsureMemberExists<TEntity>(string? propNameOrField, string? exceptionMessage = null)
where TEntity : class
{
Expand All @@ -59,6 +103,19 @@ public static void EnsureMemberExists<TEntity>(string? propNameOrField, string?
}
}

/// <summary>
/// Ases the member expression.
/// </summary>
/// <param name="expression">The expression.</param>
/// <returns></returns>
/// <exception cref="ArgumentException">
/// $"Your expression '{expressionString}' cant be used. Nested accessors like 'o => o.NestedObject.Foo' at " +
/// $"a parent level are not allowed. You should create a dedicated faker for " +
/// $"NestedObject like new Faker<NestedObject>().RuleFor(o => o.Foo, ...) with its own rules " +
/// $"that define how 'Foo' is generated.
/// or
/// Expression was not of the form 'x => x.Property or x => x.Field'.
/// </exception>
public static MemberExpression? AsMemberExpression(this Expression expression)
{
var expressionString = expression.ToString();
Expand Down Expand Up @@ -91,6 +148,15 @@ public static void EnsureMemberExists<TEntity>(string? propNameOrField, string?
return memberExpression;
}

/// <summary>
/// Sets the field.
/// </summary>
/// <typeparam name="TDep">The type of the dep.</typeparam>
/// <typeparam name="TKeyProp">The type of the key property.</typeparam>
/// <param name="target">The target.</param>
/// <param name="propExpression">The property expression.</param>
/// <param name="value">The value.</param>
/// <returns></returns>
public static void SetField<TDep, TKeyProp>(TDep target, Expression<Func<TDep, TKeyProp?>> propExpression, TKeyProp value)
{
try
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
using AutoBogus;

using NineteenSevenFour.Testing.Example.Domain.Model;

namespace NineteenSevenFour.Testing.FluentBogus.UnitTest.Faker;
using System.Diagnostics.CodeAnalysis;

namespace NineteenSevenFour.Testing.Example.Domain.Faker;

[ExcludeFromCodeCoverage]
public class PersonFaker : AutoFaker<PersonModel>
{
public PersonFaker(int Id) : this()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<SignAssembly>True</SignAssembly>
<DelaySign>True</DelaySign>
<AssemblyOriginatorKeyFile>..\nineteensevenfour-public.snk</AssemblyOriginatorKeyFile>
<ApplicationIcon>..\NineteenFourSeven_logo.ico</ApplicationIcon>
</PropertyGroup>

<ItemGroup>
<Content Include="..\NineteenFourSeven_logo.ico" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="AutoBogus" Version="2.13.1" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<SignAssembly>True</SignAssembly>
<DelaySign>True</DelaySign>
<AssemblyOriginatorKeyFile>..\nineteensevenfour-public.snk</AssemblyOriginatorKeyFile>
<ApplicationIcon>..\NineteenFourSeven_logo.ico</ApplicationIcon>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@
<ProjectReference Include="..\NineteenSevenFour.Testing.FluentBogus\NineteenSevenFour.Testing.FluentBogus.csproj" />
</ItemGroup>

<ItemGroup>
<InternalsVisibleTo Include="NineteenSevenFour.Testing.FluentBogus.AutoMapper.UnitTest, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e114a017453ade67701d8efc0553940300ac3dd115f674722bd08adeb6931852e10d08d0c41176cd1f73ebe5b7558441efdc0e9e664d99dd3980c3305ed338072852ed74b8cbab3d53c54de5e8ba34b32e17cd2969f7393f161b3f98aeaeacef61c92465a3264118327ec551d6b6286192d111c550ee1f0275fdb3df15d109c0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<SignAssembly>True</SignAssembly>
<DelaySign>True</DelaySign>
<AssemblyOriginatorKeyFile>..\nineteensevenfour-public.snk</AssemblyOriginatorKeyFile>
<ApplicationIcon>..\NineteenFourSeven_logo.ico</ApplicationIcon>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
global using AutoBogus;
global using Xunit;
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,7 @@
<ProjectReference Include="..\NineteenSevenFour.Testing.Core\NineteenSevenFour.Testing.Core.csproj" />
</ItemGroup>

<ItemGroup>
<InternalsVisibleTo Include="NineteenSevenFour.Testing.FluentBogus.Relation.UnitTest, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e114a017453ade67701d8efc0553940300ac3dd115f674722bd08adeb6931852e10d08d0c41176cd1f73ebe5b7558441efdc0e9e664d99dd3980c3305ed338072852ed74b8cbab3d53c54de5e8ba34b32e17cd2969f7393f161b3f98aeaeacef61c92465a3264118327ec551d6b6286192d111c550ee1f0275fdb3df15d109c0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using FluentAssertions;

using NineteenSevenFour.Testing.Example.Domain.Model;
using NineteenSevenFour.Testing.FluentBogus.Extension;

namespace NineteenSevenFour.Testing.FluentBogus.UnitTest;

public class FluentBogusBuilder_Fake
{
[Fact]
public void Should_Return_ABuilder_WhenCalled()
{
// Arrange

// Act
var builder = FluentBogusBuilder.Fake<PersonModel>();

// Assert
builder.Should()
.NotBeNull().And
.BeOfType<FluentBogusBuilder<PersonModel>>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using FluentAssertions;

using NineteenSevenFour.Testing.Example.Domain.Faker;
using NineteenSevenFour.Testing.Example.Domain.Model;
using NineteenSevenFour.Testing.FluentBogus.Extension;

namespace NineteenSevenFour.Testing.FluentBogus.UnitTest;

public class FluentBogusBuilder_Generate
{
[Fact]
public void Should_ReturnAnInstanceOfEntity_WhenCalled_WithoutSkipOrConfigOrSeed()
{
// Arrange
var builder = FluentBogusBuilder.Fake<PersonModel>().With<PersonFaker> ();
var typedBuilder = builder as FluentBogusBuilder<PersonFaker, PersonModel>;

// Act
var person = builder.Generate();

// Assert
person.Should().NotBeNull();
#pragma warning disable CS8602 // Dereference of a possibly null reference.
typedBuilder.skipProperties.Should().HaveCount(0);
#pragma warning restore CS8602 // Dereference of a possibly null reference.
}

[Fact]
public void Should_ReturnAnInstanceOfEntity_WhenCalled_WithSkip()
{
// Arrange
var builder = FluentBogusBuilder.Fake<PersonModel>().With<PersonFaker>();
var typedBuilder = builder as FluentBogusBuilder<PersonFaker, PersonModel>;

// Act
var person = builder.Skip(p => p.Addresses).Generate();

// Assert
person.Should().NotBeNull();
#pragma warning disable CS8602 // Dereference of a possibly null reference.
typedBuilder.skipProperties.Should().HaveCount(1);
#pragma warning restore CS8602 // Dereference of a possibly null reference.
}

[Fact]
public void Should_ReturnAnInstanceOfEntity_WhenCalled_WithConfig()
{
// Arrange
var builder = FluentBogusBuilder.Fake<PersonModel>().With<PersonFaker>();
var typedBuilder = builder as FluentBogusBuilder<PersonFaker, PersonModel>;

// Act
var person = builder.UseConfig(b => b.WithTreeDepth(1)).Generate();

// Assert
person.Should().NotBeNull();
#pragma warning disable CS8602 // Dereference of a possibly null reference.
typedBuilder.skipProperties.Should().HaveCount(0);
typedBuilder.fakerConfigBuilder.Should().NotBeNull();
#pragma warning restore CS8602 // Dereference of a possibly null reference.
}

[Fact]
public void Should_ReturnAnArrayOfInstanceOfEntity_WhenCalled_WithoutSkipOrConfigOrSeed()
{
// Arrange
var builder = FluentBogusBuilder.Fake<PersonModel>().With<PersonFaker>();
var typedBuilder = builder as FluentBogusBuilder<PersonFaker, PersonModel>;

// Act
var persons = builder.Generate(2);

// Assert
persons.Should().NotBeNullOrEmpty().And.HaveCount(2);
#pragma warning disable CS8602 // Dereference of a possibly null reference.
typedBuilder.skipProperties.Should().HaveCount(0);
#pragma warning restore CS8602 // Dereference of a possibly null reference.
}

[Fact]
public void Should_ReturnAnArrayOfInstanceOfEntity_WhenCalled_WithSkip()
{
// Arrange
var builder = FluentBogusBuilder.Fake<PersonModel>().With<PersonFaker>();
var typedBuilder = builder as FluentBogusBuilder<PersonFaker, PersonModel>;

// Act
var persons = builder.Skip(p => p.Addresses).Generate(2);

// Assert
persons.Should().NotBeNullOrEmpty().And.HaveCount(2);
#pragma warning disable CS8602 // Dereference of a possibly null reference.
typedBuilder.skipProperties.Should().HaveCount(1);
#pragma warning restore CS8602 // Dereference of a possibly null reference.
}

[Fact]
public void Should_ReturnAnArrayOfInstanceOfEntity_WhenCalled_WithConfig()
{
// Arrange
var builder = FluentBogusBuilder.Fake<PersonModel>().With<PersonFaker>();
var typedBuilder = builder as FluentBogusBuilder<PersonFaker, PersonModel>;

// Act
var persons = builder.UseConfig(b => b.WithTreeDepth(1)).Generate(2);

// Assert
persons.Should().NotBeNullOrEmpty().And.HaveCount(2);
#pragma warning disable CS8602 // Dereference of a possibly null reference.
typedBuilder.skipProperties.Should().HaveCount(0);
typedBuilder.fakerConfigBuilder.Should().NotBeNull();
#pragma warning restore CS8602 // Dereference of a possibly null reference.
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using FluentAssertions;

using NineteenSevenFour.Testing.Example.Domain.Faker;
using NineteenSevenFour.Testing.Example.Domain.Model;
using NineteenSevenFour.Testing.FluentBogus.Extension;

namespace NineteenSevenFour.Testing.FluentBogus.UnitTest;

public class FluentBogusBuilder_RuleSetString
{
[Fact]
public void Should_ReturnJoinedList_WhenCalled_WithRuleset()
{
// Arrange
var builder = FluentBogusBuilder.Fake<PersonModel>().With<PersonFaker>();

// Act
builder.UseRuleSet("rule1", "rule2");

// Assert
var typedBuilder = builder as FluentBogusBuilder<PersonFaker, PersonModel>;
Assert.NotNull(typedBuilder);
typedBuilder.RuleSetString.Should()
.NotBeNullOrEmpty()
.And
.Be("rule1,rule2");
}

[Fact]
public void Should_ReturnEmptyString_WhenCalled_WithoutRuleset()
{
// Arrange
var builder = FluentBogusBuilder.Fake<PersonModel>().With<PersonFaker>();

// Act

// Assert
var typedBuilder = builder as FluentBogusBuilder<PersonFaker, PersonModel>;
Assert.NotNull(typedBuilder);
typedBuilder.RuleSetString.Should()
.BeNullOrEmpty();
}
}
Loading

0 comments on commit 24bd68e

Please sign in to comment.