2011-05-22 16:53:21 +00:00
|
|
|
// ReSharper disable RedundantUsingDirective
|
2011-04-08 04:03:46 +00:00
|
|
|
using System;
|
2011-04-07 03:34:48 +00:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Linq.Expressions;
|
2011-04-08 04:03:46 +00:00
|
|
|
using System.Runtime.CompilerServices;
|
2011-04-07 03:34:48 +00:00
|
|
|
using AutoMoq.Unity;
|
|
|
|
using Microsoft.Practices.Unity;
|
|
|
|
using Moq;
|
|
|
|
using Moq.Language.Flow;
|
|
|
|
|
2011-04-08 04:03:46 +00:00
|
|
|
[assembly: InternalsVisibleTo("AutoMoq.Tests")]
|
|
|
|
|
2011-04-07 03:34:48 +00:00
|
|
|
namespace AutoMoq
|
|
|
|
{
|
|
|
|
public class AutoMoqer
|
|
|
|
{
|
2011-04-22 19:15:47 +00:00
|
|
|
internal readonly MockBehavior DefaultBehavior = MockBehavior.Default;
|
2011-04-10 02:44:01 +00:00
|
|
|
internal Type ResolveType;
|
2011-04-07 03:34:48 +00:00
|
|
|
private IUnityContainer container;
|
|
|
|
private IDictionary<Type, object> registeredMocks;
|
|
|
|
|
|
|
|
public AutoMoqer()
|
|
|
|
{
|
|
|
|
SetupAutoMoqer(new UnityContainer());
|
|
|
|
}
|
|
|
|
|
2011-04-22 19:15:47 +00:00
|
|
|
public AutoMoqer(MockBehavior defaultBehavior)
|
|
|
|
{
|
|
|
|
DefaultBehavior = defaultBehavior;
|
|
|
|
SetupAutoMoqer(new UnityContainer());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-04-07 03:34:48 +00:00
|
|
|
internal AutoMoqer(IUnityContainer container)
|
|
|
|
{
|
|
|
|
SetupAutoMoqer(container);
|
|
|
|
}
|
|
|
|
|
|
|
|
public virtual T Resolve<T>()
|
|
|
|
{
|
2011-04-20 07:44:13 +00:00
|
|
|
ResolveType = typeof(T);
|
2011-04-08 06:50:30 +00:00
|
|
|
var result = container.Resolve<T>();
|
2011-04-20 07:44:13 +00:00
|
|
|
SetConstant(result);
|
2011-04-08 06:50:30 +00:00
|
|
|
ResolveType = null;
|
|
|
|
return result;
|
2011-04-07 03:34:48 +00:00
|
|
|
}
|
|
|
|
|
2011-04-22 19:15:47 +00:00
|
|
|
public virtual Mock<T> GetMock<T>() where T : class
|
|
|
|
{
|
|
|
|
return GetMock<T>(DefaultBehavior);
|
|
|
|
}
|
|
|
|
|
|
|
|
public virtual Mock<T> GetMock<T>(MockBehavior behavior) where T : class
|
2011-04-07 03:34:48 +00:00
|
|
|
{
|
2011-04-08 06:50:30 +00:00
|
|
|
ResolveType = null;
|
2011-04-07 03:34:48 +00:00
|
|
|
var type = GetTheMockType<T>();
|
|
|
|
if (GetMockHasNotBeenCalledForThisType(type))
|
2011-04-10 00:14:51 +00:00
|
|
|
{
|
|
|
|
CreateANewMockAndRegisterIt<T>(type, behavior);
|
|
|
|
}
|
2011-04-07 03:34:48 +00:00
|
|
|
|
2011-04-10 00:14:51 +00:00
|
|
|
var mock = TheRegisteredMockForThisType<T>(type);
|
|
|
|
|
|
|
|
if (behavior != MockBehavior.Default && mock.Behavior == MockBehavior.Default)
|
|
|
|
{
|
|
|
|
throw new InvalidOperationException("Unable to change be behaviour of a an existing mock.");
|
|
|
|
}
|
|
|
|
|
|
|
|
return mock;
|
2011-04-07 03:34:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
internal virtual void SetMock(Type type, Mock mock)
|
|
|
|
{
|
|
|
|
if (registeredMocks.ContainsKey(type) == false)
|
|
|
|
registeredMocks.Add(type, mock);
|
|
|
|
}
|
|
|
|
|
2011-04-20 07:44:13 +00:00
|
|
|
public virtual void SetConstant<T>(T instance)
|
2011-04-08 04:03:46 +00:00
|
|
|
{
|
|
|
|
container.RegisterInstance(instance);
|
|
|
|
SetMock(instance.GetType(), null);
|
|
|
|
}
|
|
|
|
|
2011-04-07 03:34:48 +00:00
|
|
|
public ISetup<T> Setup<T>(Expression<Action<T>> expression) where T : class
|
|
|
|
{
|
|
|
|
return GetMock<T>().Setup(expression);
|
|
|
|
}
|
|
|
|
|
|
|
|
public ISetup<T, TResult> Setup<T, TResult>(Expression<Func<T, TResult>> expression) where T : class
|
|
|
|
{
|
|
|
|
return GetMock<T>().Setup(expression);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Verify<T>(Expression<Action<T>> expression) where T : class
|
|
|
|
{
|
|
|
|
GetMock<T>().Verify(expression);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Verify<T>(Expression<Action<T>> expression, string failMessage) where T : class
|
|
|
|
{
|
|
|
|
GetMock<T>().Verify(expression, failMessage);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Verify<T>(Expression<Action<T>> expression, Times times) where T : class
|
|
|
|
{
|
|
|
|
GetMock<T>().Verify(expression, times);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Verify<T>(Expression<Action<T>> expression, Times times, string failMessage) where T : class
|
|
|
|
{
|
|
|
|
GetMock<T>().Verify(expression, times, failMessage);
|
|
|
|
}
|
|
|
|
|
2011-04-10 00:14:51 +00:00
|
|
|
public void VerifyAllMocks()
|
|
|
|
{
|
|
|
|
foreach (var registeredMock in registeredMocks)
|
|
|
|
{
|
|
|
|
var mock = registeredMock.Value as Mock;
|
2011-04-22 20:13:32 +00:00
|
|
|
if (mock != null)
|
|
|
|
mock.VerifyAll();
|
2011-04-10 00:14:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-10 02:44:01 +00:00
|
|
|
#region private methods
|
|
|
|
|
|
|
|
private void SetupAutoMoqer(IUnityContainer container)
|
|
|
|
{
|
|
|
|
this.container = container;
|
2011-04-22 19:15:47 +00:00
|
|
|
container.RegisterInstance(this);
|
2011-04-10 02:44:01 +00:00
|
|
|
|
2011-04-22 19:15:47 +00:00
|
|
|
registeredMocks = new Dictionary<Type, object>();
|
2011-04-10 02:44:01 +00:00
|
|
|
AddTheAutoMockingContainerExtensionToTheContainer(container);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void AddTheAutoMockingContainerExtensionToTheContainer(IUnityContainer container)
|
|
|
|
{
|
|
|
|
container.AddNewExtension<AutoMockingContainerExtension>();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
private Mock<T> TheRegisteredMockForThisType<T>(Type type) where T : class
|
|
|
|
{
|
2011-04-20 07:44:13 +00:00
|
|
|
return (Mock<T>)registeredMocks.Where(x => x.Key == type).First().Value;
|
2011-04-10 02:44:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void CreateANewMockAndRegisterIt<T>(Type type, MockBehavior behavior) where T : class
|
|
|
|
{
|
|
|
|
var mock = new Mock<T>(behavior);
|
|
|
|
container.RegisterInstance(mock.Object);
|
|
|
|
SetMock(type, mock);
|
|
|
|
}
|
|
|
|
|
|
|
|
private bool GetMockHasNotBeenCalledForThisType(Type type)
|
|
|
|
{
|
|
|
|
return registeredMocks.ContainsKey(type) == false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static Type GetTheMockType<T>() where T : class
|
|
|
|
{
|
2011-04-20 07:44:13 +00:00
|
|
|
return typeof(T);
|
2011-04-10 02:44:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
2011-04-07 03:34:48 +00:00
|
|
|
}
|
|
|
|
}
|