Skip to content

Commit 32fba8c

Browse files
committed
Added OptionsBuilder for per test configuration setup (#125)
1 parent e413ee3 commit 32fba8c

File tree

17 files changed

+179
-38
lines changed

17 files changed

+179
-38
lines changed

samples/MusicStore/MusicStore.Test/Controllers/CheckoutControllerTest.cs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,12 @@ public void CompleteShouldReturnViewWithCorrectIdWithCorrectOrder()
7272
MyMvc
7373
.Controller<CheckoutController>()
7474
.WithAuthenticatedUser(user => user.WithUsername("TestUser"))
75-
.WithServiceSetupFor<MusicStoreContext>(ms =>
76-
{
77-
ms.Orders.Add(new Order
75+
.WithDbContext(dbContext =>
76+
dbContext.WithSet<MusicStoreContext, Order>(o => o.Add(new Order
7877
{
7978
OrderId = 1,
8079
Username = "TestUser"
81-
});
82-
83-
ms.SaveChanges();
84-
})
80+
})))
8581
.Calling(c => c.Complete(From.Services<MusicStoreContext>(), 1))
8682
.ShouldReturn()
8783
.View(1);
@@ -93,16 +89,12 @@ public void CompleteShouldReturnViewWithErrorWithIncorrectOrder()
9389
MyMvc
9490
.Controller<CheckoutController>()
9591
.WithAuthenticatedUser(user => user.WithUsername("TestUser"))
96-
.WithServiceSetupFor<MusicStoreContext>(ms =>
97-
{
98-
ms.Orders.Add(new Order
92+
.WithDbContext(dbContext =>
93+
dbContext.WithSet<MusicStoreContext, Order>(o => o.Add(new Order
9994
{
10095
OrderId = 1,
10196
Username = "AnotherUser"
102-
});
103-
104-
ms.SaveChanges();
105-
})
97+
})))
10698
.Calling(c => c.Complete(From.Services<MusicStoreContext>(), 1))
10799
.ShouldReturn()
108100
.View("Error");

samples/MusicStore/MusicStore.Test/TestStartup.cs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,8 @@ public TestStartup(IHostingEnvironment env)
2121
public void ConfigureTestServices(IServiceCollection services)
2222
{
2323
base.ConfigureServices(services);
24-
25-
services.Remove<DbContextOptions<MusicStoreContext>>();
26-
services.AddDbContext<MusicStoreContext>(opts =>
27-
{
28-
opts.UseInMemoryDatabase();
29-
30-
((IDbContextOptionsBuilderInfrastructure)opts).AddOrUpdateExtension(new ScopedInMemoryOptionsExtension());
31-
});
32-
24+
3325
services.ReplaceSingleton<SignInManager<ApplicationUser>, MockedSignInManager>();
3426
}
35-
36-
private class ScopedInMemoryOptionsExtension : InMemoryOptionsExtension
37-
{
38-
public override void ApplyServices(IServiceCollection services)
39-
{
40-
services.Replace<IInMemoryStore, InMemoryStore>(ServiceLifetime.Scoped);
41-
}
42-
}
4327
}
4428
}

src/MyTested.AspNetCore.Mvc.Core/Builders/Controllers/ControllerServiceBuilder.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public partial class ControllerBuilder<TController>
1515
{
1616
/// <inheritdoc />
1717
public IAndControllerBuilder<TController> WithServiceSetupFor<TService>(Action<TService> scopedServiceSetup)
18+
where TService : class
1819
{
1920
CommonValidator.CheckForNullReference(scopedServiceSetup, nameof(scopedServiceSetup));
2021
ServiceValidator.ValidateScopedServiceLifetime<TService>(nameof(WithServiceSetupFor));

src/MyTested.AspNetCore.Mvc.Core/IControllerBuilder.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ public interface IControllerBuilder<TController> : IBaseTestBuilder
101101
/// <typeparam name="TService">Type of service to configure.</typeparam>
102102
/// <param name="scopedServiceSetup">Action configuring the service before running the test case.</param>
103103
/// <returns>The same <see cref="IControllerBuilder{TController}"/>.</returns>
104-
IAndControllerBuilder<TController> WithServiceSetupFor<TService>(Action<TService> scopedServiceSetup);
104+
IAndControllerBuilder<TController> WithServiceSetupFor<TService>(Action<TService> scopedServiceSetup)
105+
where TService : class;
105106

106107
/// <summary>
107108
/// Sets null value to the constructor service dependency of the given type.

src/MyTested.AspNetCore.Mvc.Core/Utilities/Validators/ServiceValidator.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,19 @@ public static void ValidateServiceExists<TService>(TService service)
3737
/// <typeparam name="TService">Type of service to validate.</typeparam>
3838
/// <param name="methodName">Name of the calling method.</param>
3939
public static void ValidateScopedServiceLifetime<TService>(string methodName)
40+
where TService : class
4041
{
41-
var serviceLifetime = TestServiceProvider.GetServiceLifetime<TService>();
42+
ValidateScopedServiceLifetime(typeof(TService), methodName);
43+
}
44+
45+
/// <summary>
46+
/// Validates whether service exists and has scoped <see cref="ServiceLifetime"/>.
47+
/// </summary>
48+
/// <param name="service">Type of service to validate.</param>
49+
/// <param name="methodName">Name of the calling method.</param>
50+
public static void ValidateScopedServiceLifetime(Type service, string methodName)
51+
{
52+
var serviceLifetime = TestServiceProvider.GetServiceLifetime(service);
4253
if (serviceLifetime != ServiceLifetime.Scoped)
4354
{
4455
throw new InvalidOperationException($"The '{methodName}' method can be used only for services with scoped lifetime.");

src/MyTested.AspNetCore.Mvc.EntityFrameworkCore/Builders/Data/DbContextBuilder.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
using Contracts.Data;
66
using Internal.TestContexts;
77
using Microsoft.EntityFrameworkCore;
8-
using Microsoft.Extensions.DependencyInjection;
98
using Utilities.Validators;
10-
using Internal;
9+
1110
/// <summary>
1211
/// Used for building <see cref="DbContext"/>.
1312
/// </summary>

src/MyTested.AspNetCore.Mvc.EntityFrameworkCore/Builders/Data/DbContextTestBuilder.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using Base;
55
using Contracts.Data;
66
using Exceptions;
7-
using Internal;
87
using Internal.TestContexts;
98
using Microsoft.EntityFrameworkCore;
109
using Utilities;

src/MyTested.AspNetCore.Mvc.EntityFrameworkCore/Internal/HttpTestContextEntityFrameworkExtensions.cs renamed to src/MyTested.AspNetCore.Mvc.EntityFrameworkCore/Internal/TestContexts/HttpTestContextEntityFrameworkExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace MyTested.AspNetCore.Mvc.Internal
1+
namespace MyTested.AspNetCore.Mvc.Internal.TestContexts
22
{
33
using Microsoft.Extensions.DependencyInjection;
44
using TestContexts;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace MyTested.AspNetCore.Mvc.Builders.Contracts
2+
{
3+
using System;
4+
5+
public interface IOptionsBuilder
6+
{
7+
void For<TOptions>(Action<TOptions> optionsSetup) where TOptions : class, new();
8+
}
9+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
namespace MyTested.AspNetCore.Mvc.Builders
2+
{
3+
using System;
4+
using Base;
5+
using Contracts;
6+
using Internal.TestContexts;
7+
using Utilities.Validators;
8+
9+
public class OptionsBuilder : BaseTestBuilder, IOptionsBuilder
10+
{
11+
public OptionsBuilder(HttpTestContext testContext)
12+
: base(testContext)
13+
{
14+
}
15+
16+
public void For<TOptions>(Action<TOptions> optionsSetup)
17+
where TOptions : class, new()
18+
{
19+
CommonValidator.CheckForNullReference(optionsSetup, nameof(optionsSetup));
20+
21+
optionsSetup(this.TestContext.GetOptions<TOptions>());
22+
}
23+
}
24+
}

0 commit comments

Comments
 (0)