From 47c295c12469984e5d7274231e4a1e8180d427fb Mon Sep 17 00:00:00 2001 From: Andy Longhurst Date: Tue, 24 Oct 2023 08:57:13 +0100 Subject: [PATCH 1/3] add autofixture and autodataattribute --- .../Blog.Tests.Integration.csproj | 3 +++ .../AutoNSubstitudeDataAttribute.cs | 27 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 SqlOnly/Blog.Tests.Integration/Customisation/AutoNSubstitudeDataAttribute.cs diff --git a/SqlOnly/Blog.Tests.Integration/Blog.Tests.Integration.csproj b/SqlOnly/Blog.Tests.Integration/Blog.Tests.Integration.csproj index eb26106..9058ca2 100644 --- a/SqlOnly/Blog.Tests.Integration/Blog.Tests.Integration.csproj +++ b/SqlOnly/Blog.Tests.Integration/Blog.Tests.Integration.csproj @@ -9,6 +9,9 @@ + + + diff --git a/SqlOnly/Blog.Tests.Integration/Customisation/AutoNSubstitudeDataAttribute.cs b/SqlOnly/Blog.Tests.Integration/Customisation/AutoNSubstitudeDataAttribute.cs new file mode 100644 index 0000000..132c2fc --- /dev/null +++ b/SqlOnly/Blog.Tests.Integration/Customisation/AutoNSubstitudeDataAttribute.cs @@ -0,0 +1,27 @@ +using AutoFixture; +using AutoFixture.AutoNSubstitute; +using AutoFixture.Xunit2; + +namespace Blog.Tests.Integration.Customisation; + +public class AutoNSubstituteDataAttribute : AutoDataAttribute +{ + public AutoNSubstituteDataAttribute(params Type[] optionalCustomizationTypes) + : base(() => BuildFixture(optionalCustomizationTypes)) + { + } + + // ReSharper disable once ParameterTypeCanBeEnumerable.Local + private static IFixture BuildFixture(Type[] optionalCustomizationTypes) + { + var fixture = new Fixture() + .Customize(new AutoNSubstituteCustomization()); + + foreach (var customizationType in optionalCustomizationTypes) + { + fixture.Customize((ICustomization)Activator.CreateInstance(customizationType)); + } + + return fixture; + } +} \ No newline at end of file From bfda471d152f5c8de02f462112731f3ed90abaf0 Mon Sep 17 00:00:00 2001 From: Andy Longhurst Date: Tue, 24 Oct 2023 08:58:38 +0100 Subject: [PATCH 2/3] refactored service method --- SqlOnly/Blog/Services/BlogService.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/SqlOnly/Blog/Services/BlogService.cs b/SqlOnly/Blog/Services/BlogService.cs index 30310bc..b038aa0 100644 --- a/SqlOnly/Blog/Services/BlogService.cs +++ b/SqlOnly/Blog/Services/BlogService.cs @@ -16,6 +16,11 @@ public async Task CreatePost(int userId, string title, string text) { var post = new Post(userId, title, text); + return await CreatePost(post); + } + + public async Task CreatePost(Post post) + { _dbContext.Set().Add(post); await _dbContext.SaveChangesAsync(); From 463d4fc6f0e636f0a5cf28b97ab6d48558906422 Mon Sep 17 00:00:00 2001 From: Andy Longhurst Date: Tue, 24 Oct 2023 09:04:50 +0100 Subject: [PATCH 3/3] completed test --- .../Extensions/ReflectionExtensions.cs | 25 +++++++++++++ .../Services/BlogServiceTests.cs | 35 +++++++++++++++++-- 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 SqlOnly/Blog.Tests.Integration/Extensions/ReflectionExtensions.cs diff --git a/SqlOnly/Blog.Tests.Integration/Extensions/ReflectionExtensions.cs b/SqlOnly/Blog.Tests.Integration/Extensions/ReflectionExtensions.cs new file mode 100644 index 0000000..ea39296 --- /dev/null +++ b/SqlOnly/Blog.Tests.Integration/Extensions/ReflectionExtensions.cs @@ -0,0 +1,25 @@ +#nullable enable +using System.Reflection; + +namespace Blog.Tests.Integration.Extensions; + +public static class ReflectionExtensions +{ + public static T SetThroughReflection(this T entity, string propertyName, object? value) + { + var properties = typeof(T).GetProperties(BindingFlags.FlattenHierarchy | + BindingFlags.Instance | + BindingFlags.Public).ToArray(); + + var named = properties.Where(x => x.Name == propertyName).ToArray(); + + var property = typeof(T).GetProperties(BindingFlags.FlattenHierarchy | + BindingFlags.Instance | + BindingFlags.Public) + .Single(s => s.SetMethod != null && s.Name == propertyName); + + property.SetValue(entity, value); + + return entity; + } +} \ No newline at end of file diff --git a/SqlOnly/Blog.Tests.Integration/Services/BlogServiceTests.cs b/SqlOnly/Blog.Tests.Integration/Services/BlogServiceTests.cs index 3324356..4a0a7f0 100644 --- a/SqlOnly/Blog.Tests.Integration/Services/BlogServiceTests.cs +++ b/SqlOnly/Blog.Tests.Integration/Services/BlogServiceTests.cs @@ -3,6 +3,8 @@ using Blog.Data; using Blog.Data.Entities; using Blog.Services; +using Blog.Tests.Integration.Customisation; +using Blog.Tests.Integration.Extensions; using FluentAssertions; using Microsoft.EntityFrameworkCore; using Xunit; @@ -29,11 +31,11 @@ public async Task Inserts_a_Post() { var title = "A test post"; var text = "This post was made in an integration test and was saved to a SQL instance managed by Accelergreat."; - + var user = GetComponent().Users.First(); await using var testContext = CreateContext(); - + var service = new BlogService(testContext); var resultingPost = await service.CreatePost(user.UserId, title, text); @@ -80,4 +82,33 @@ public async Task Inserts_a_Comment() databasePost.PostId.Should().Be(post.PostId); databasePost.Text.Should().Be(text); } + + [Theory, AutoNSubstituteData] + public async Task Inserts_a_Post_from__AutoFixture(Post post) + { + var user = GetComponent().Users.First(); + + post.SetThroughReflection(nameof(Post.UserId), user.UserId); + + await using var testContext = CreateContext(); + + var service = new BlogService(testContext); + + var resultingPost = await service.CreatePost(post); + + // Assert the result from the service is as expected + resultingPost.UserId.Should().Be(user.UserId); + resultingPost.Title.Should().Be(post.Title); + resultingPost.Text.Should().Be(post.Text); + + // Assert the data stored to the database is as expected + // This is done on a separate DbContext to ensure in-memory instances are not used + await using var assertionContext = CreateContext(); + var databasePost = await assertionContext.Set().SingleAsync(x => x.PostId == resultingPost.PostId); + + databasePost.UserId.Should().Be(user.UserId); + databasePost.Title.Should().Be(post.Title); + databasePost.Text.Should().Be(post.Text); + } + } \ No newline at end of file