Skip to content

Commit eea556c

Browse files
authored
Skip substitution creation if type is already registered (#54)
1 parent a55cd23 commit eea556c

File tree

5 files changed

+40
-20
lines changed

5 files changed

+40
-20
lines changed

AutofacContrib.NSubstitute.Tests/AutoSubstituteCollectionFixture.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,5 +150,27 @@ public void TestIReadOnlyListCorrectlyResolves()
150150
Assert.That(component.ServiceItems.Contains(mockA.Value), Is.True);
151151
Assert.That(component.ServiceItems.Contains(mockB.Value), Is.True);
152152
}
153+
154+
[Test]
155+
public void OpenGenericResolvesCorrectly()
156+
{
157+
using var mock = AutoSubstitute.Configure()
158+
.ConfigureBuilder(b => b
159+
.RegisterGeneric(typeof(OpenGeneric<>))
160+
.As(typeof(IOpenGeneric<>)))
161+
.Build();
162+
163+
var open = mock.Resolve<IOpenGeneric<string>>();
164+
165+
Assert.That(open, Is.TypeOf<OpenGeneric<string>>());
166+
}
167+
168+
public class OpenGeneric<T> : IOpenGeneric<T>
169+
{
170+
}
171+
172+
public interface IOpenGeneric<T>
173+
{
174+
}
153175
}
154176
}

AutofacContrib.NSubstitute.Tests/TypesToSkipForMockingFixture.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Autofac.Core.Registration;
22
using NUnit.Framework;
3+
using System;
34
using System.Collections.Generic;
45

56
namespace AutofacContrib.NSubstitute.Tests
@@ -17,12 +18,13 @@ public void WithoutOption()
1718

1819
var items = mock.Resolve<IDependency[]>();
1920

21+
Assert.AreEqual(2, items.Length);
2022
Assert.AreEqual(impl1.Value, items[0]);
2123
Assert.AreEqual(impl2.Value, items[1]);
22-
Assert.That(items[2], Is.NSubstituteMock);
2324
}
2425

2526
[Test]
27+
[Obsolete]
2628
public void ManuallyAddTypeToSkip()
2729
{
2830
var mock = AutoSubstitute.Configure()
@@ -36,13 +38,9 @@ public void ManuallyAddTypeToSkip()
3638
}
3739

3840
[Test]
39-
public void DisableMockGenerationOnProvide()
41+
public void RegisteredTypesAreNotMocked()
4042
{
4143
var mock = AutoSubstitute.Configure()
42-
.ConfigureOptions(options =>
43-
{
44-
options.AutomaticallySkipMocksForProvidedValues = true;
45-
})
4644
.Provide<IDependency, Impl1>(out var impl1)
4745
.Provide<IDependency, Impl2>(out var impl2)
4846
.Build();

AutofacContrib.NSubstitute/AutoSubstituteBuilder.cs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,6 @@ public AutoSubstituteBuilder Provide<TService, TImplementation>(out IProvidedVal
172172

173173
providedValue = CreateProvidedValue<TService>(c => c.ResolveKeyed<TService>(key));
174174

175-
SkipMockIfNeeded<TService>();
176-
177175
return this;
178176
}
179177

@@ -188,8 +186,6 @@ public AutoSubstituteBuilder Provide<TService>(TService instance)
188186
{
189187
_builder.RegisterInstance(instance);
190188

191-
SkipMockIfNeeded<TService>();
192-
193189
return this;
194190
}
195191

@@ -251,14 +247,6 @@ public AutoSubstituteBuilder ResolveAndSubstituteFor<TService>(params Parameter[
251247
return this;
252248
}
253249

254-
private void SkipMockIfNeeded<T>()
255-
{
256-
if (_options.AutomaticallySkipMocksForProvidedValues)
257-
{
258-
_options.TypesToSkipForMocking.Add(typeof(T));
259-
}
260-
}
261-
262250
private SubstituteForBuilder<TService> CreateSubstituteForBuilder<TService>(Func<TService> factory, bool isSubstituteFor)
263251
where TService : class
264252
{

AutofacContrib.NSubstitute/AutoSubstituteOptions.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
using Autofac.Builder;
33
using System;
44
using System.Collections.Generic;
5+
using System.ComponentModel;
56

67
namespace AutofacContrib.NSubstitute
78
{
89
public class AutoSubstituteOptions
910
{
10-
private readonly static Func<ContainerBuilder, IContainer> _defaultContainerBuilder = b => b.Build();
11+
private readonly static Func<ContainerBuilder, Autofac.IContainer> _defaultContainerBuilder = b => b.Build();
1112

1213
internal bool AutoInjectProperties { get; set; }
1314

@@ -24,16 +25,20 @@ public class AutoSubstituteOptions
2425
/// <summary>
2526
/// Gets a collection of types that will be skipped during generation of NSubstitute mocks.
2627
/// </summary>
28+
[Obsolete]
29+
[EditorBrowsable(EditorBrowsableState.Never)]
2730
public ICollection<Type> TypesToSkipForMocking { get; } = new HashSet<Type>();
2831

2932
/// <summary>
3033
/// Gets or sets a flag indicating whether mocks should be excluded for provided values. This will automatically add values given to Provide methods to <see cref="TypesToSkipForMocking"/>.
3134
/// </summary>
35+
[Obsolete]
36+
[EditorBrowsable(EditorBrowsableState.Never)]
3237
public bool AutomaticallySkipMocksForProvidedValues { get; set; }
3338

3439
/// <summary>
3540
/// Gets or sets a factory to create an <see cref="IContainer"/> given a <see cref="ContainerBuilder"/>. This defaults to simply calling <see cref="ContainerBuilder.Build()"/>.
3641
/// </summary>
37-
public Func<ContainerBuilder, IContainer> BuildContainerFactory { get; set; } = _defaultContainerBuilder;
42+
public Func<ContainerBuilder, Autofac.IContainer> BuildContainerFactory { get; set; } = _defaultContainerBuilder;
3843
}
3944
}

AutofacContrib.NSubstitute/NSubstituteRegistrationHandler.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,14 @@ public IEnumerable<IComponentRegistration> RegistrationsFor
6060
service is DecoratorService)
6161
return Enumerable.Empty<IComponentRegistration>();
6262

63+
#pragma warning disable CS0612 // Type or member is obsolete
6364
if (_options.TypesToSkipForMocking.Contains(typedService.ServiceType))
65+
#pragma warning restore CS0612 // Type or member is obsolete
66+
{
67+
return Enumerable.Empty<IComponentRegistration>();
68+
}
69+
70+
if (registrationAccessor(service).Any())
6471
{
6572
return Enumerable.Empty<IComponentRegistration>();
6673
}

0 commit comments

Comments
 (0)