/src/UnitTests/IOC/Factories/FactoryTests.cs

http://github.com/philiplaureano/LinFu · C# · 185 lines · 135 code · 36 blank · 14 comment · 1 complexity · 14414d2457b89956b54806fdc46f5c38 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.Serialization;
  4. using LinFu.IoC;
  5. using LinFu.IoC.Factories;
  6. using LinFu.IoC.Interfaces;
  7. using Moq;
  8. using Xunit;
  9. using SampleLibrary;
  10. using SampleLibrary.IOC.BugFixes;
  11. namespace LinFu.UnitTests.IOC.Factories
  12. {
  13. public class FactoryTests : BaseTestFixture
  14. {
  15. private Func<IFactoryRequest, ISerializable> _createInstance;
  16. protected override void Init()
  17. {
  18. // Create a new mock service instance on each
  19. // factory method call
  20. _createInstance = request => new Mock<ISerializable>().Object;
  21. }
  22. protected override void Term()
  23. {
  24. _createInstance = null;
  25. }
  26. [Fact]
  27. public void GenericFactoryAdapterShouldCallUntypedFactoryInstance()
  28. {
  29. var container = new ServiceContainer();
  30. var mockFactory = new Mock<IFactory<ISerializable>>();
  31. var mockService = new Mock<ISerializable>();
  32. var adapter = new FactoryAdapter<ISerializable>(mockFactory.Object);
  33. // The adapter itself should call the container on creation
  34. mockFactory.Expect(f => f.CreateInstance(It.Is<IFactoryRequest>(request => request.Container == container)))
  35. .Returns(mockService.Object);
  36. Assert.NotNull(adapter);
  37. var factoryRequest = new FactoryRequest
  38. {
  39. ServiceName = null,
  40. ServiceType = typeof(ISerializable),
  41. Container = container
  42. };
  43. adapter.CreateInstance(factoryRequest);
  44. mockFactory.VerifyAll();
  45. }
  46. [Fact]
  47. public void OncePerRequestFactoryShouldCreateUniqueInstances()
  48. {
  49. var factory = new OncePerRequestFactory<ISerializable>(_createInstance);
  50. var first = factory.CreateInstance(null);
  51. var second = factory.CreateInstance(null);
  52. // Both instances must be unique
  53. Assert.NotSame(first, second);
  54. Assert.NotNull(first);
  55. Assert.NotNull(second);
  56. }
  57. [Fact]
  58. public void OncePerThreadFactoryShouldCreateTheSameInstanceFromWithinTheSameThread()
  59. {
  60. IFactory<ISerializable> localFactory = new OncePerThreadFactory<ISerializable>(_createInstance);
  61. var first = localFactory.CreateInstance(null);
  62. var second = localFactory.CreateInstance(null);
  63. // The two instances should be the same
  64. // since they were created from the same thread
  65. Assert.NotNull(first);
  66. Assert.Same(first, second);
  67. }
  68. [Fact]
  69. public void OncePerThreadFactoryShouldCreateUniqueInstancesFromDifferentThreads()
  70. {
  71. IFactory<ISerializable> localFactory = new OncePerThreadFactory<ISerializable>(_createInstance);
  72. var resultList = new List<ISerializable>();
  73. Action<IFactory<ISerializable>> doCreate = factory =>
  74. {
  75. var instance = factory.CreateInstance(null);
  76. var otherInstance = factory.CreateInstance(null);
  77. // The two instances
  78. // within the same thread must match
  79. Assert.Same(instance, otherInstance);
  80. lock (resultList)
  81. {
  82. resultList.Add(instance);
  83. }
  84. };
  85. // Create the instance in another thread
  86. var asyncResult = doCreate.BeginInvoke(localFactory, null, null);
  87. var localInstance = localFactory.CreateInstance(null);
  88. // Wait for the previous thread
  89. // to finish executing
  90. doCreate.EndInvoke(asyncResult);
  91. Assert.True(resultList.Count > 0);
  92. // Collect the results from the other thread
  93. var instanceFromOtherThread = resultList[0];
  94. Assert.NotNull(localInstance);
  95. Assert.NotNull(instanceFromOtherThread);
  96. Assert.NotSame(localInstance, instanceFromOtherThread);
  97. }
  98. [Fact]
  99. public void ShouldBeAbleToCreateClosedGenericTypeUsingACustomFactoryInstance()
  100. {
  101. var container = new ServiceContainer();
  102. container.Initialize();
  103. container.LoadFrom(typeof(MyClass<>).Assembly);
  104. // Get ServiceNotFoundException here instead of a service instance.
  105. var serviceName = "frobozz";
  106. var service = container.GetService<MyClass<string>>(serviceName);
  107. Console.WriteLine("foo");
  108. Assert.Equal(serviceName, service.Value);
  109. }
  110. [Fact]
  111. public void ShouldBeAbleToInstantiateCustomFactoryWithServiceArgumentsInConstructor()
  112. {
  113. var mock = new Mock<ISampleService>();
  114. var container = new ServiceContainer();
  115. container.LoadFromBaseDirectory("*.dll");
  116. container.AddService(mock.Object);
  117. var result = container.GetService<string>("SampleFactoryWithConstructorArguments");
  118. Assert.NotNull(result);
  119. Assert.NotEmpty(result);
  120. }
  121. [Fact]
  122. public void ShouldLoadStronglyTypedFactoryFromLoadFromExtensionMethod()
  123. {
  124. var container = new ServiceContainer();
  125. container.LoadFrom(typeof(SampleClass).Assembly);
  126. var serviceInstance = container.GetService<ISampleService>("Test");
  127. Assert.NotNull(serviceInstance);
  128. }
  129. [Fact]
  130. public void SingletonFactoryShouldCreateTheSameInstanceOnce()
  131. {
  132. var factory = new SingletonFactory<ISerializable>(_createInstance);
  133. var container = new ServiceContainer();
  134. var request = new FactoryRequest
  135. {
  136. ServiceName = null,
  137. Arguments = new object[0],
  138. Container = container,
  139. ServiceType = typeof(ISerializable)
  140. };
  141. var first = factory.CreateInstance(request);
  142. var second = factory.CreateInstance(request);
  143. // Both instances must be the same
  144. Assert.Same(first, second);
  145. Assert.NotNull(first);
  146. Assert.NotNull(second);
  147. }
  148. }
  149. }