Skip to content

Commit

Permalink
Merge pull request #118 from TheTribe/release/3.10-beta.4
Browse files Browse the repository at this point in the history
Release/3.10-beta.4 to master
  • Loading branch information
TheTribe committed Oct 4, 2013
2 parents c3cd70a + 559db91 commit fc7f668
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 88 deletions.
6 changes: 6 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

The following log details the outward-facing changes made to code-patterns since its first migration to GitHub.

## 3.10-beta.4 ##

- Fixes for `IMoqContainer` ([issue 114](https://github.com/TheTribe/code-patterns/issues/114))
- Calls to `Create<TService>` now either return the registered instance, or a mock. No hidden updates.
- Calls to `Create<TService, TImplementation>` update the container with the implementation type, and return the newly-registered instance.

## 3.10-beta.3 ##

- Extracted `Patterns.Configuration.InMemoryConfigurationSource` from `Patterns.Testing.Configuration.TestConfigurationSource` ([issue 110](https://github.com/TheTribe/code-patterns/issues/110))
Expand Down
46 changes: 24 additions & 22 deletions src/Patterns.Testing.Autofac/Moq/AutofacMoqContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ public AutofacMoqContainer(IContainer container) : base(container)
/// </returns>
public Mock<TService> Mock<TService>() where TService : class
{
var service = Try.Get(() => Create<TService>());
TService service = Try.Get(Create<TService>);
var existingMock = service as IMocked<TService>;
if (existingMock != null) return existingMock.Mock;

var mock = MoqRegistrationSource.Repository.Create<TService>();
Mock<TService> mock = MoqRegistrationSource.Repository.Create<TService>();
Update(mock.Object);
return mock;
}
Expand All @@ -85,17 +85,25 @@ public AutofacMoqContainer(IContainer container) : base(container)
/// for all unregistered dependencies.
/// </summary>
/// <typeparam name="TService">The type of the service.</typeparam>
/// <param name="activator">The optional activator.</param>
/// <returns>
/// The service instance.
/// </returns>
public TService Create<TService>(Func<IMoqContainer, TService> activator = null) where TService : class
public TService Create<TService>() where TService : class
{
return ResolveOrCreate<TService>(activator == null
? (builder => builder.RegisterType<TService>()
.PropertiesAutowired(PropertyWiringOptions.PreserveSetValues))
: (Action<ContainerBuilder>) (builder => builder.Register(c => activator(this))
.PropertiesAutowired(PropertyWiringOptions.PreserveSetValues)));
return Container.Resolve<TService>();
}

/// <summary>
/// Creates an instance of the specified implementation (as the specified service),
/// injecting mocked objects for all unregistered dependencies.
/// </summary>
/// <typeparam name="TService">The type of the service.</typeparam>
/// <typeparam name="TImplementation">The type of the implementation.</typeparam>
/// <returns></returns>
public TService Create<TService, TImplementation>() where TService : class where TImplementation : TService
{
Update<TService, TImplementation>();
return Create<TService>();
}

/// <summary>
Expand All @@ -109,7 +117,7 @@ public AutofacMoqContainer(IContainer container) : base(container)
public IMoqContainer Update<TService, TImplementation>() where TService : class where TImplementation : TService
{
UpdateWithBuilder(builder => builder.RegisterType<TImplementation>().As<TService>()
.PropertiesAutowired(PropertyWiringOptions.PreserveSetValues));
.PropertiesAutowired(PropertyWiringOptions.PreserveSetValues));

return this;
}
Expand All @@ -125,7 +133,7 @@ public AutofacMoqContainer(IContainer container) : base(container)
public IMoqContainer Update<TService>(TService instance) where TService : class
{
UpdateWithBuilder(builder => builder.RegisterInstance(instance).As<TService>()
.PropertiesAutowired(PropertyWiringOptions.PreserveSetValues));
.PropertiesAutowired(PropertyWiringOptions.PreserveSetValues));

return this;
}
Expand All @@ -141,17 +149,17 @@ public AutofacMoqContainer(IContainer container) : base(container)
public IMoqContainer Update<TService>(Func<IMoqContainer, TService> activator) where TService : class
{
UpdateWithBuilder(builder => builder.Register(c => activator(this)).As<TService>()
.PropertiesAutowired(PropertyWiringOptions.PreserveSetValues));
.PropertiesAutowired(PropertyWiringOptions.PreserveSetValues));

return this;
}

/// <summary>
/// Updates the container using the specified module.
/// Updates the container using the specified module.
/// </summary>
/// <param name="module">The module.</param>
/// <returns>
/// The container.
/// The container.
/// </returns>
public IAutofacMoqContainer Update(Module module)
{
Expand All @@ -160,11 +168,11 @@ public IAutofacMoqContainer Update(Module module)
}

/// <summary>
/// Updates the container using the specified registration.
/// Updates the container using the specified registration.
/// </summary>
/// <param name="registration">The registration.</param>
/// <returns>
/// The container.
/// The container.
/// </returns>
public IAutofacMoqContainer Update(Action<ContainerBuilder> registration)
{
Expand All @@ -178,11 +186,5 @@ private void UpdateWithBuilder(Action<ContainerBuilder> registration)
registration(builder);
builder.Update(Container);
}

private T ResolveOrCreate<T>(Action<ContainerBuilder> registration)
{
if (!Container.IsRegistered<T>()) UpdateWithBuilder(registration);
return Container.Resolve<T>();
}
}
}
36 changes: 19 additions & 17 deletions src/Patterns.Testing/Moq/IMoqContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,57 +28,59 @@
namespace Patterns.Testing.Moq
{
/// <summary>
/// Provides an IoC container designed for maximum configurability
/// during tests, and for tight integration with Moq.
/// Provides an IoC container designed for maximum configurability
/// during tests, and for tight integration with Moq.
/// </summary>
public interface IMoqContainer
{
/// <summary>
/// Gets the locator.
/// Gets the locator.
/// </summary>
/// <value>
/// The locator.
/// The locator.
/// </value>
IServiceLocator Locator { get; }

/// <summary>
/// Retrieves the mock for the specified service type.
/// Retrieves the mock for the specified service type.
/// </summary>
/// <typeparam name="TService">The type of the service.</typeparam>
/// <returns>The service mock.</returns>
Mock<TService> Mock<TService>() where TService : class;

/// <summary>
/// Creates an instance of the specified service, injecting mocked objects
/// for all unregistered dependencies.
/// Creates an instance of the specified service, injecting mocked objects
/// for all unregistered dependencies.
/// </summary>
/// <typeparam name="TService">The type of the service.</typeparam>
/// <param name="activator">The optional activator.</param>
/// <returns>The service instance.</returns>
TService Create<TService>(Func<IMoqContainer, TService> activator = null) where TService : class;
TService Create<TService>() where TService : class;

/// <summary>
/// Updates this instance by registering the implementation type as the service type.
/// Creates an instance of the specified implementation (as the specified service),
/// injecting mocked objects for all unregistered dependencies.
/// </summary>
/// <typeparam name="TService">The type of the service.</typeparam>
/// <typeparam name="TImplementation">The type of the implementation.</typeparam>
TService Create<TService, TImplementation>() where TService : class where TImplementation : TService;

/// <summary>
/// Updates this instance by registering the implementation type as the service type.
/// </summary>
/// <typeparam name="TService">The type of the service.</typeparam>
/// <typeparam name="TImplementation">The type of the implementation.</typeparam>
/// <returns>The container.</returns>
IMoqContainer Update<TService, TImplementation>() where TService : class where TImplementation : TService;

/// <summary>
/// Updates this instance by registering an instance of the specified service.
/// Updates this instance by registering an instance of the specified service.
/// </summary>
/// <typeparam name="TService">The type of the service.</typeparam>
/// <param name="instance">The instance.</param>
/// <returns>The container.</returns>
IMoqContainer Update<TService>(TService instance) where TService : class;

/// <summary>
/// Updates this instance by registering the specified activator as the service type.
/// Updates this instance by registering the specified activator as the service type.
/// </summary>
/// <typeparam name="TService">The type of the service.</typeparam>
/// <param name="activator">The activator.</param>
/// <returns>The container</returns>
IMoqContainer Update<TService>(Func<IMoqContainer, TService> activator) where TService : class;
}
}
2 changes: 1 addition & 1 deletion src/Patterns/SolutionAssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@
[assembly: ComVisible(false)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyVersion("3.10.0")]
[assembly: AssemblyInformationalVersion("3.10.0-beta3")]
[assembly: AssemblyInformationalVersion("3.10.0-beta4")]
2 changes: 1 addition & 1 deletion src/Patterns/SolutionAssemblyInfo.settings.tt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Settings.Initialize(
majorNumber: 3,
minorNumber: 10,
patchNumber: 0,
buildNumber: 3,
buildNumber: 4,
buildLevel: BuildLevels.Beta
);
#><#+
Expand Down
26 changes: 16 additions & 10 deletions src/_specs/Features/Testing/Moq/Autofac/AutofacMoqContainer.feature
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,37 @@

Background:
Given I have an Autofac/Moq test container
Then the Autofac/Moq test container should have 0 registrations for my test object
Then the Autofac/Moq test container should have 0 registrations for my test interface

Scenario: Create an unregistered object
When I create an object using the test container
Scenario: Create an unregistered interface
When I create an instance of an interface using the test container
Then the test container should have given me an object
And the Autofac/Moq test container should have 1 registration for my test object
And the Autofac/Moq test container should have 1 registration for my test interface
And the object retrieved by the test container should be a mock-based type

Scenario: Create an unregistered creatable class
When I create an instance of a creatable class using the test container
Then the test container should have given me an object
And the Autofac/Moq test container should have 1 registration for my test interface
And the object retrieved by the test container should not be a mock-based type

Scenario: Create a registered object
When I register an object with the test container
And I create an object using the test container
Then the Autofac/Moq test container should have 1 registration for my test object
And I create an instance of an interface using the test container
Then the Autofac/Moq test container should have 1 registration for my test interface
And the test container should have given me an object
And the object retrieved by the test container should not be a mock-based type

Scenario: Override a registered object
When I register an object with the test container
And I create an object using the test container
Then the Autofac/Moq test container should have 1 registration for my test object
And I create an instance of an interface using the test container
Then the Autofac/Moq test container should have 1 registration for my test interface
And the test container should have given me an object
And the object retrieved by the test container should not be a mock-based type

When I create a mock of the object using the test container
And I create an object using the test container
Then the Autofac/Moq test container should have 2 registrations for my test object
And I create an instance of an interface using the test container
Then the Autofac/Moq test container should have 2 registrations for my test interface
And the test container should have given me an object
And the test container should have given me a mock of the object
And the object retrieved by the test container should be a mock-based type
Loading

0 comments on commit fc7f668

Please sign in to comment.