Skip to content

Commit

Permalink
Merge pull request #1 from skbkontur/inject-attribute-fabrics-handling
Browse files Browse the repository at this point in the history
Inject attribute fabrics handling
  • Loading branch information
AndrewKostousov authored Aug 9, 2019
2 parents 3d70efb + 20ca5e1 commit e3ff29a
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;

using NUnit.Framework;

namespace GroboContainer.NUnitExtensions.Tests.Container
{
[GroboTestFixture]
public class InjectedAttribute_TestFactories : InjectedAttributeTestBase
{
[GroboSetUp]
public void SetUp()
{
GroboTestMachineryTrace.ClearTrace();
}

[Test]
public void TestSimpleFactory()
{
var service = factory();
Assert.That(service, Is.Not.Null);
service.Foo(41);
Assert.That(GroboTestMachineryTrace.TraceLines, Is.EqualTo(new[] {"ServiceWithNoDependencies.Foo(p=41)"}));
}

[Test]
public void TestFactoryFromString()
{
var service = factoryFromString("qxx");
Assert.That(service, Is.Not.Null);
service.Hoo(42);
Assert.That(GroboTestMachineryTrace.TraceLines, Is.EqualTo(new[] {"ServiceDependingOnString.Hoo(p=qxx, q=42)"}));
}

[Test]
public void TestFactory4()
{
var service = factory4(new[] {"qxx"}, new[] {1}, new short[] {2}, new byte[] {3});
Assert.That(service, Is.Not.Null);
service.Qoo(43);
Assert.That(GroboTestMachineryTrace.TraceLines, Is.EqualTo(new[] {"ServiceDependingOnManyStrings.Qoo(a=qxx, b=1, c=2, d=3, p=43)"}));
}

[Injected]
private Func<IServiceWithNoDependencies> factory;

[Injected]
private Func<string, IServiceDependingOnString> factoryFromString;

[Injected]
private Func<string[], int[], short[], byte[], IServiceWithManyDependencies> factory4;
}

public interface IServiceWithManyDependencies
{
void Qoo(int p);
}

public class ServiceWithManyDependencies : IServiceWithManyDependencies
{
private readonly string[] a;
private readonly int[] b;
private readonly short[] c;
private readonly byte[] d;

public ServiceWithManyDependencies(string[] a, int[] b, short[] c, byte[] d)
{
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}

public void Qoo(int p)
{
GroboTestMachineryTrace.Log($"ServiceDependingOnManyStrings.Qoo(" +
$"a={(a == null ? "null" : string.Join(", ", a))}, " +
$"b={(b == null ? "null" : string.Join(", ", b))}, " +
$"c={(c == null ? "null" : string.Join(", ", c))}, " +
$"d={(d == null ? "null" : string.Join(", ", d))}, " +
$"p={p})");
}
}
}
19 changes: 17 additions & 2 deletions GroboContainer.NUnitExtensions/Impl/GroboTestAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,21 @@ private static void InvokeWrapperMethod([CanBeNull] MethodInfo wrapperMethod, [N
private static void InjectFixtureFields([NotNull] GroboTestSuiteContextData suiteContext, [NotNull] object testFixture)
{
foreach (var fieldInfo in testFixture.GetType().GetFieldsForInjection())
fieldInfo.SetValue(testFixture, suiteContext.Container.Get(fieldInfo.FieldType));
fieldInfo.SetValue(testFixture, InstantiateField(suiteContext, fieldInfo));
}

[NotNull]
private static object InstantiateField([NotNull] GroboTestSuiteContextData suiteContext, [NotNull] FieldInfo fieldInfo)
{
var fieldType = fieldInfo.FieldType;
if (typeof(Delegate).IsAssignableFrom(fieldType))
{
if (fieldType.IsGenericType && supportedFactoryFuncTypes.Contains(fieldType.GetGenericTypeDefinition()))
return suiteContext.Container.GetCreationFunc(fieldType);
throw new InvalidOperationException($"Unable to instantiate injected field '{fieldInfo.Name}' of delegate type '{fieldType}'. " +
$"Following delegate types are supported: {string.Join(", ", supportedFactoryFuncTypes.Select(x => x.Name))}");
}
return suiteContext.Container.Get(fieldType);
}

private static void EnsureAppDomainInitialization()
Expand Down Expand Up @@ -188,6 +202,7 @@ private static void OnAppDomainUnload()
private static readonly object appDomainInitializationLock = new object();
private static readonly ConditionalWeakTable<object, object> setUpedFixtures = new ConditionalWeakTable<object, object>();
private static readonly ConcurrentDictionary<string, SuiteDescriptor> suiteDescriptors = new ConcurrentDictionary<string, SuiteDescriptor>();
private static readonly Type[] supportedFactoryFuncTypes = {typeof(Func<>), typeof(Func<,>), typeof(Func<,,>), typeof(Func<,,,>), typeof(Func<,,,,>)};

private class SuiteDescriptor
{
Expand Down Expand Up @@ -234,7 +249,7 @@ public void Destroy([NotNull] string suiteName)
private static ContainerConfiguration GetContainerConfiguration([NotNull] string suiteName, [NotNull] Assembly testAssembly)
{
const string containerConfiguratorTypeName = "GroboTestMachineryContainerConfigurator";
var containerConfiguratorTypes = testAssembly.GetExportedTypes().Where(t=> t.IsClass && t.Name == containerConfiguratorTypeName).ToList();
var containerConfiguratorTypes = testAssembly.GetExportedTypes().Where(t => t.IsClass && t.Name == containerConfiguratorTypeName).ToList();
if (!containerConfiguratorTypes.Any())
throw new InvalidOperationException($"Failed to get container configuration for test suite {suiteName}. There is no {containerConfiguratorTypeName} type in test assembly: {testAssembly}");
if (containerConfiguratorTypes.Count > 1)
Expand Down

0 comments on commit e3ff29a

Please sign in to comment.