You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
366 lines
11 KiB
366 lines
11 KiB
using JetBrains.Annotations;
|
|
using LightweightIocContainer;
|
|
using LightweightIocContainer.Exceptions;
|
|
using LightweightIocContainer.Interfaces;
|
|
using LightweightIocContainer.Interfaces.Installers;
|
|
using LightweightIocContainer.Interfaces.Registrations;
|
|
using Moq;
|
|
using NUnit.Framework;
|
|
|
|
namespace Test.LightweightIocContainer;
|
|
|
|
[TestFixture]
|
|
public class IocContainerTest
|
|
{
|
|
private interface ITest
|
|
{
|
|
|
|
}
|
|
|
|
private interface IFoo
|
|
{
|
|
|
|
}
|
|
|
|
private class Test : ITest
|
|
{
|
|
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
private class TestConstructor : ITest
|
|
{
|
|
public TestConstructor(string name, Test test)
|
|
{
|
|
|
|
}
|
|
|
|
public TestConstructor(Test test, string name = null)
|
|
{
|
|
|
|
}
|
|
|
|
public TestConstructor(IFoo foo, string name)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
private class TestPrivateConstructor : ITest
|
|
{
|
|
private TestPrivateConstructor()
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
private class TestMultipleConstructors : ITest
|
|
{
|
|
public TestMultipleConstructors(string name, bool success)
|
|
{
|
|
|
|
}
|
|
|
|
public TestMultipleConstructors(string name)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
private class TestWithFoo : ITest
|
|
{
|
|
public TestWithFoo(IFoo testFoo) => TestFoo = testFoo;
|
|
|
|
[UsedImplicitly]
|
|
public IFoo TestFoo { get; }
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
private class Foo : IFoo
|
|
{
|
|
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
private class FooConstructor : IFoo
|
|
{
|
|
public FooConstructor(string test)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
private class MultitonScope
|
|
{
|
|
|
|
}
|
|
|
|
|
|
private IocContainer _iocContainer;
|
|
|
|
[SetUp]
|
|
public void SetUp() => _iocContainer = new IocContainer();
|
|
|
|
[TearDown]
|
|
public void TearDown() => _iocContainer.Dispose();
|
|
|
|
|
|
[Test]
|
|
public void TestInstall()
|
|
{
|
|
Mock<IIocInstaller> installerMock = new();
|
|
IIocContainer returnedContainer = _iocContainer.Install(installerMock.Object);
|
|
|
|
installerMock.Verify(m => m.Install(It.IsAny<IRegistrationCollector>()), Times.Once);
|
|
|
|
Assert.AreEqual(_iocContainer, returnedContainer);
|
|
}
|
|
|
|
[Test]
|
|
public void TestInstallMultiple()
|
|
{
|
|
Mock<IIocInstaller> installer1Mock = new();
|
|
Mock<IIocInstaller> installer2Mock = new();
|
|
Mock<IIocInstaller> installer3Mock = new();
|
|
|
|
IIocContainer returnedContainer = _iocContainer.Install(installer1Mock.Object, installer2Mock.Object, installer3Mock.Object);
|
|
|
|
installer1Mock.Verify(m => m.Install(It.IsAny<IRegistrationCollector>()), Times.Once);
|
|
installer2Mock.Verify(m => m.Install(It.IsAny<IRegistrationCollector>()), Times.Once);
|
|
installer3Mock.Verify(m => m.Install(It.IsAny<IRegistrationCollector>()), Times.Once);
|
|
|
|
Assert.AreEqual(_iocContainer, returnedContainer);
|
|
}
|
|
|
|
[Test]
|
|
public void TestRegister() => Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add<ITest, Test>()));
|
|
|
|
[Test]
|
|
public void TestRegisterTypeWithoutInterface() => Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add<Test>()));
|
|
|
|
[Test]
|
|
public void TestRegisterMultiton() => Assert.DoesNotThrow(() => _iocContainer.Register(r => r.AddMultiton<ITest, Test, MultitonScope>()));
|
|
|
|
[Test]
|
|
public void TestInvalidMultitonRegistration() => Assert.Throws<InvalidRegistrationException>(() => _iocContainer.Register(r => r.Add<ITest, Test>(Lifestyle.Multiton)));
|
|
|
|
[Test]
|
|
public void TestRegisterMultipleDifferent()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest, Test>());
|
|
MultipleRegistrationException exception = Assert.Throws<MultipleRegistrationException>(() => _iocContainer.Register(r => r.Add<ITest, TestConstructor>()));
|
|
Assert.AreEqual(typeof(ITest), exception?.Type);
|
|
}
|
|
|
|
[Test]
|
|
public void TestRegisterMultipleSame()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest, Test>());
|
|
Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add<ITest, Test>()));
|
|
}
|
|
|
|
[Test]
|
|
public void TestRegisterMultipleSameWithParameters()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest, Test>().WithParameters("test", 1, new Foo()));
|
|
Assert.DoesNotThrow(() => _iocContainer.Register(r => r.Add<ITest, Test>().WithParameters("test", 1, new Foo())));
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveNotRegistered()
|
|
{
|
|
TypeNotRegisteredException exception = Assert.Throws<TypeNotRegisteredException>(() => _iocContainer.Resolve<ITest>());
|
|
Assert.AreEqual(typeof(ITest), exception?.Type);
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolve()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest, Test>());
|
|
|
|
ITest resolvedTest = _iocContainer.Resolve<ITest>();
|
|
|
|
Assert.IsInstanceOf<Test>(resolvedTest);
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveWithoutInterface()
|
|
{
|
|
_iocContainer.Register(r => r.Add<Test>());
|
|
|
|
Test resolvedTest = _iocContainer.Resolve<Test>();
|
|
|
|
Assert.IsInstanceOf<Test>(resolvedTest);
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveInterfaceWithoutImplementation()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest>());
|
|
Assert.Throws<InvalidRegistrationException>(() => _iocContainer.Resolve<ITest>());
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveImplementationRegisteredWithInterface()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest, Test>());
|
|
|
|
Test resolvedTest = _iocContainer.Resolve<Test>();
|
|
|
|
Assert.IsInstanceOf<Test>(resolvedTest);
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveWithParams()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest, TestConstructor>());
|
|
|
|
ITest resolvedTest = _iocContainer.Resolve<ITest>("Test", new Test());
|
|
|
|
Assert.IsInstanceOf<TestConstructor>(resolvedTest);
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveWithMissingParam()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest, TestConstructor>());
|
|
_iocContainer.Register(r => r.Add<Test, Test>()); //this registration is abnormal and should only be used in unit tests
|
|
|
|
ITest resolvedTest = _iocContainer.Resolve<ITest>("Test");
|
|
|
|
Assert.IsInstanceOf<TestConstructor>(resolvedTest);
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveSingleton()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest, Test>(Lifestyle.Singleton));
|
|
|
|
ITest resolvedTest = _iocContainer.Resolve<ITest>();
|
|
ITest secondResolvedTest = _iocContainer.Resolve<ITest>();
|
|
|
|
Assert.AreEqual(resolvedTest, secondResolvedTest);
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveMultiton()
|
|
{
|
|
_iocContainer.Register(r => r.AddMultiton<ITest, Test, MultitonScope>());
|
|
|
|
MultitonScope scope1 = new();
|
|
MultitonScope scope2 = new();
|
|
|
|
ITest resolvedTest1 = _iocContainer.Resolve<ITest>(scope1);
|
|
ITest resolvedTest2 = _iocContainer.Resolve<ITest>(scope1);
|
|
ITest resolvedTest3 = _iocContainer.Resolve<ITest>(scope2);
|
|
|
|
Assert.AreSame(resolvedTest1, resolvedTest2);
|
|
Assert.AreNotSame(resolvedTest1, resolvedTest3);
|
|
Assert.AreNotSame(resolvedTest2, resolvedTest3);
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveMultitonNoArgs()
|
|
{
|
|
_iocContainer.Register(r => r.AddMultiton<ITest, Test, MultitonScope>());
|
|
|
|
MultitonResolveException exception = Assert.Throws<MultitonResolveException>(() => _iocContainer.Resolve<ITest>());
|
|
Assert.AreEqual(typeof(ITest), exception?.Type);
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveMultitonWrongArgs()
|
|
{
|
|
_iocContainer.Register(r => r.AddMultiton<ITest, Test, MultitonScope>());
|
|
|
|
MultitonResolveException exception = Assert.Throws<MultitonResolveException>(() => _iocContainer.Resolve<ITest>(new object()));
|
|
Assert.AreEqual(typeof(ITest), exception?.Type);
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveTransient()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest, Test>());
|
|
|
|
ITest resolvedTest = _iocContainer.Resolve<ITest>();
|
|
ITest secondResolvedTest = _iocContainer.Resolve<ITest>();
|
|
|
|
Assert.AreNotEqual(resolvedTest, secondResolvedTest);
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveNoMatchingConstructor()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest, TestConstructor>());
|
|
NoMatchingConstructorFoundException exception = Assert.Throws<NoMatchingConstructorFoundException>(() => _iocContainer.Resolve<ITest>());
|
|
Assert.AreEqual(typeof(TestConstructor), exception?.Type);
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveNoMatchingConstructorNotThrownWrongly()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest, TestMultipleConstructors>());
|
|
Assert.DoesNotThrow(() => _iocContainer.Resolve<ITest>("Name"));
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolvePrivateConstructor()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest, TestPrivateConstructor>());
|
|
NoPublicConstructorFoundException exception = Assert.Throws<NoPublicConstructorFoundException>(() => _iocContainer.Resolve<ITest>());
|
|
Assert.AreEqual(typeof(TestPrivateConstructor), exception?.Type);
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveSingleTypeRegistrationWithFactoryMethod()
|
|
{
|
|
_iocContainer.Register(r => r.Add<IFoo, Foo>());
|
|
_iocContainer.Register(r => r.Add<ITest>().WithFactoryMethod(c => new TestConstructor(c.Resolve<IFoo>(), "someName")));
|
|
|
|
ITest test = _iocContainer.Resolve<ITest>();
|
|
|
|
Assert.NotNull(test);
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveParameterIsRegisteredWithParameters()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest, TestConstructor>());
|
|
_iocContainer.Register(r => r.Add<IFoo, FooConstructor>().WithParameters("TestString"));
|
|
|
|
ITest test = _iocContainer.Resolve<ITest>("testName");
|
|
|
|
Assert.IsInstanceOf<TestConstructor>(test);
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveParameterWithTwoParameters()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest, TestWithFoo>().WithParameters(new Foo()));
|
|
_iocContainer.Register(r => r.Add<IFoo, FooConstructor>(Lifestyle.Singleton).WithParameters("TestString"));
|
|
|
|
_iocContainer.Resolve<ITest>();
|
|
}
|
|
|
|
[Test]
|
|
public void TestResolveTypeWithToManyParameters()
|
|
{
|
|
_iocContainer.Register(r => r.Add<ITest, TestWithFoo>().WithParameters(new Foo()));
|
|
Assert.Throws<NoMatchingConstructorFoundException>(() => _iocContainer.Resolve<ITest>(new Foo()));
|
|
}
|
|
|
|
[Test]
|
|
public void TestIsTypeRegistered()
|
|
{
|
|
Assert.False(_iocContainer.IsTypeRegistered<ITest>());
|
|
|
|
_iocContainer.Register(r => r.Add<ITest, Test>());
|
|
Assert.True(_iocContainer.IsTypeRegistered<ITest>());
|
|
|
|
_iocContainer.Register(r => r.Add<Test>());
|
|
Assert.True(_iocContainer.IsTypeRegistered<Test>());
|
|
}
|
|
} |