Skip to content

Commit 69e3e33

Browse files
author
Bart Koelman
committed
Added unit tests for create resource expressions
1 parent a636422 commit 69e3e33

File tree

3 files changed

+101
-25
lines changed

3 files changed

+101
-25
lines changed

src/JsonApiDotNetCore/Internal/IResourceFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public NewExpression CreateNewExpression(Type resourceType)
7272
try
7373
{
7474
object constructorArgument =
75-
ActivatorUtilities.CreateInstance(_serviceProvider, constructorParameter.ParameterType);
75+
ActivatorUtilities.GetServiceOrCreateInstance(_serviceProvider, constructorParameter.ParameterType);
7676

7777
constructorArguments.Add(Expression.Constant(constructorArgument));
7878
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System;
2+
using System.ComponentModel.Design;
3+
using System.Linq.Expressions;
4+
using JsonApiDotNetCore.Internal;
5+
using JsonApiDotNetCoreExample.Data;
6+
using Microsoft.AspNetCore.Authentication;
7+
using Microsoft.EntityFrameworkCore;
8+
using Xunit;
9+
10+
namespace UnitTests.Models
11+
{
12+
public sealed class ResourceConstructionExpressionTests
13+
{
14+
[Fact]
15+
public void When_resource_has_default_constructor_it_must_succeed()
16+
{
17+
// Arrange
18+
var factory = new DefaultResourceFactory(new ServiceContainer());
19+
20+
// Act
21+
NewExpression newExpression = factory.CreateNewExpression(typeof(ResourceWithoutConstructor));
22+
23+
// Assert
24+
var function = Expression
25+
.Lambda<Func<ResourceWithoutConstructor>>(newExpression)
26+
.Compile();
27+
28+
ResourceWithoutConstructor resource = function();
29+
Assert.NotNull(resource);
30+
}
31+
32+
[Fact]
33+
public void When_resource_has_constructor_with_injectable_parameter_it_must_succeed()
34+
{
35+
// Arrange
36+
var contextOptions = new DbContextOptionsBuilder<AppDbContext>().Options;
37+
var systemClock = new FrozenSystemClock();
38+
var appDbContext = new AppDbContext(contextOptions, systemClock);
39+
40+
using var serviceContainer = new ServiceContainer();
41+
serviceContainer.AddService(typeof(DbContextOptions<AppDbContext>), contextOptions);
42+
serviceContainer.AddService(typeof(ISystemClock), systemClock);
43+
serviceContainer.AddService(typeof(AppDbContext), appDbContext);
44+
45+
var factory = new DefaultResourceFactory(serviceContainer);
46+
47+
// Act
48+
NewExpression newExpression = factory.CreateNewExpression(typeof(ResourceWithDbContextConstructor));
49+
50+
// Assert
51+
var function = Expression
52+
.Lambda<Func<ResourceWithDbContextConstructor>>(newExpression)
53+
.Compile();
54+
55+
ResourceWithDbContextConstructor resource = function();
56+
Assert.NotNull(resource);
57+
Assert.Equal(appDbContext, resource.AppDbContext);
58+
}
59+
60+
[Fact]
61+
public void When_resource_has_constructor_with_string_parameter_it_must_fail()
62+
{
63+
// Arrange
64+
var factory = new DefaultResourceFactory(new ServiceContainer());
65+
66+
// Act
67+
Action action = () => factory.CreateNewExpression(typeof(ResourceWithStringConstructor));
68+
69+
// Assert
70+
var exception = Assert.Throws<InvalidOperationException>(action);
71+
Assert.Equal(
72+
"Failed to create an instance of 'UnitTests.Models.ResourceWithStringConstructor': Parameter 'text' could not be resolved.",
73+
exception.Message);
74+
}
75+
}
76+
}

test/UnitTests/Models/ResourceConstructionTests.cs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public void When_resource_has_default_constructor_that_throws_it_must_fail()
7272
// Assert
7373
var exception = Assert.Throws<InvalidOperationException>(action);
7474
Assert.Equal(
75-
"Failed to create an instance of 'UnitTests.Models.ResourceConstructionTests+ResourceWithThrowingConstructor' using its default constructor.",
75+
"Failed to create an instance of 'UnitTests.Models.ResourceWithThrowingConstructor' using its default constructor.",
7676
exception.Message);
7777
}
7878

@@ -138,40 +138,40 @@ public void When_resource_has_constructor_with_string_parameter_it_must_fail()
138138
// Assert
139139
var exception = Assert.Throws<InvalidOperationException>(action);
140140
Assert.Equal(
141-
"Failed to create an instance of 'UnitTests.Models.ResourceConstructionTests+ResourceWithStringConstructor' using injected constructor parameters.",
141+
"Failed to create an instance of 'UnitTests.Models.ResourceWithStringConstructor' using injected constructor parameters.",
142142
exception.Message);
143143
}
144+
}
144145

145-
public class ResourceWithoutConstructor : Identifiable
146-
{
147-
}
146+
public class ResourceWithoutConstructor : Identifiable
147+
{
148+
}
148149

149-
public class ResourceWithDbContextConstructor : Identifiable
150-
{
151-
public AppDbContext AppDbContext { get; }
150+
public class ResourceWithDbContextConstructor : Identifiable
151+
{
152+
public AppDbContext AppDbContext { get; }
152153

153-
public ResourceWithDbContextConstructor(AppDbContext appDbContext)
154-
{
155-
AppDbContext = appDbContext ?? throw new ArgumentNullException(nameof(appDbContext));
156-
}
154+
public ResourceWithDbContextConstructor(AppDbContext appDbContext)
155+
{
156+
AppDbContext = appDbContext ?? throw new ArgumentNullException(nameof(appDbContext));
157157
}
158+
}
158159

159-
public class ResourceWithThrowingConstructor : Identifiable
160+
public class ResourceWithThrowingConstructor : Identifiable
161+
{
162+
public ResourceWithThrowingConstructor()
160163
{
161-
public ResourceWithThrowingConstructor()
162-
{
163-
throw new ArgumentException("Failed to initialize.");
164-
}
164+
throw new ArgumentException("Failed to initialize.");
165165
}
166+
}
166167

167-
public class ResourceWithStringConstructor : Identifiable
168-
{
169-
public string Text { get; }
168+
public class ResourceWithStringConstructor : Identifiable
169+
{
170+
public string Text { get; }
170171

171-
public ResourceWithStringConstructor(string text)
172-
{
173-
Text = text ?? throw new ArgumentNullException(nameof(text));
174-
}
172+
public ResourceWithStringConstructor(string text)
173+
{
174+
Text = text ?? throw new ArgumentNullException(nameof(text));
175175
}
176176
}
177177
}

0 commit comments

Comments
 (0)