Introduction
Auto mocking allows you to get object of the type you want to test without setting up mocks by hand. All dependencies are mocked automatically (assuming they are interfaces) and injected into the type constructor. If you need to you can set up expected behavior, but you don't have to.
Requirements
You need to reference these assemblies in your test project: * Moq * Moq Contrib
Usage
AutoMock
is a mocking factory. You can ask it for the object you want to test, it will generate all dependencies for you through mocks and allow you to verify them when you're done.
You specify default mock behavior (strict or loose) through by creating custom mock factory and passing it to the 'AutoMock' constructor.
Example Classes
``` public interface IApple { void Fall(); }
public class Apple :IApple { public void Fall() { } }
public class Tree { private readonly IApple _apple;
public Tree(IApple apple)
{
_apple = apple;
}
public void Grow() {}
public void DropApple()
{
_apple.Fall();
}
} ```
Automatic Dependency Injection
Bar
constructor takes IApple
as parameter. IApple
will be mocked automatically and Mock.Object
is passed to the constructor.
```
var factory = new MockFactory(MockBehavior.Loose);
var container = new AutoMockContainer(factory);
var tree = container.Create();
tree.Grow();
factory.VerifyAll(); ```
See Resolving Parameters in AutoFac if you need to specify more parameters for the object you need to use activator with AutoMock.Create
.
Setting Up Expectations
You can always get the mock and set up expectations.
``` var factory = new MockFactory(MockBehavior.Loose); var container = new AutoMockContainer(factory);
container.GetMock< IApple >().Expect( x => x.Fall() ).Verifiable(); var tree = container.Create(); tree.DropApple();
factory.VerifyAll(); ```
Providing Your Own Implementation
You can provide an instance of an interface (no mocking will be done) or specify which class to use as default interface implementation (again, no mocking will be done).
``` var factory = new MockFactory(MockBehavior.Loose); var container = new AutoMockContainer(factory);
container.Register< IApple >( new Apple() ); // or mock.Register< IApple, Apple >(); var tree = container.Create(); tree.DropApple();
factory.VerifyAll(); ```
Verifying All Mocks
Mocks can be verified when you're done. You can also place mocks verification to the test tear down.
Base Test Class with Auto Mocking
To simplify testing even further you can use a base class for all your tests with common methods to set up mocking. I've implemented the class as part of my Netco project. Bellow is the it's current implementation at the time of writing this article.
Assuming you're using xUnit for testing something like this will work: ``` /// /// Base class for all tests. /// /// Provides base auto mocking for the tests. /// /// public abstract class AutoMockingTests : IDisposable { private MockFactory _factory;
/// <summary>
/// Initializes a new instance of the <see cref="AutoMockingTests"/> class.
/// </summary>
/// <remarks>Defaults to <see cref="MockBehavior.Loose"/>.</remarks>
protected AutoMockingTests()
{
this._factory = new MockFactory( MockBehavior.Loose );
this.Container = new AutoMockContainer( this._factory );
}
/// <summary>
/// Changes mocks behavior to <see cref="MockBehavior.Strict"/>.
/// </summary>
protected void UseStrict()
{
this._factory = new MockFactory( MockBehavior.Strict );
this.Container = new AutoMockContainer( this._factory );
}
/// <summary>
/// Forces factory verification.
/// </summary>
/// <remarks>This is called automatically by xUnit.</remarks>
public virtual void Dispose()
{
if( this.VerifyAll )
this._factory.VerifyAll();
else
this._factory.Verify();
}
/// <summary>
/// Gets or sets a value indicating whether <see cref="MockFactory.VerifyAll"/> will be used or <see cref="MockFactory.Verify"/>.
/// </summary>
/// <value><c>true</c> to use <see cref="MockFactory.VerifyAll"/>; otherwise, <c>false</c>.</value>
/// <remarks><c>false</c> be default.</remarks>
public bool VerifyAll { get; set; }
/// <summary>
/// Gets or sets the auto mocking container.
/// </summary>
/// <value>The auto mocking container.</value>
protected AutoMockContainer Container { get; private set; }
/// <summary>
/// Creates an object of the specified type.
/// </summary>
/// <typeparam name="T">A type to create.</typeparam>
/// <returns>
/// Object of the type <typeparamref name="T"/>.
/// </returns>
/// <remarks>Usually used to create objects to test. Any non-existing dependencies
/// are mocked.
/// <para>Container is used to resolve build dependencies.</para></remarks>
public T Create < T >() where T : class
{
return this.Container.Create< T >();
}
/// <summary>
/// Creates an object of the specified type.
/// </summary>
/// <typeparam name="T">A type to create.</typeparam>
/// <param name="activator">The activator used to create object.</param>
/// <returns>
/// Object of the type <typeparamref name="T"/>.
/// </returns>
/// <remarks>Usually used to create objects to test. Any non-existing dependencies
/// are mocked.
/// <para>Container is used to resolve build dependencies.</para></remarks>
/// <example>Using activator</example>
/// <code>this.Create( c => new Apple( c.Resolve< ITree> ()) )</code>
/// <seealso href="http://code.google.com/p/autofac/wiki/ResolveParameters"/>
public T Create < T > ( Func< IResolve, T > activator ) where T : class
{
return this.Container.Create( activator );
}
/// <summary>
/// Resolves an object from the container.
/// </summary>
/// <typeparam name="T">Type to resolve for.</typeparam>
/// <returns>Resolved object.</returns>
public T Resolve < T >() where T : class
{
return this.Container.Resolve< T >();
}
/// <summary>
/// Creates a mock object.
/// </summary>
/// <typeparam name="T">A type to mock.</typeparam>
/// <returns>Mocked object of the type <typeparamref name="T"/>.</returns>
/// <remarks>Used to set-up expected mock behavior when object created with <see cref="Create{T}()"/>.
/// calls on the mock.
/// <para>To set-up expected calls to mock use
/// <code>Mock< type >().Expect( x => x.Method( params )).Returns( fakeResults )</code></para></remarks>
public Mock< T > Mock < T >() where T : class
{
return this.Container.GetMock< T >();
}
/// <summary>
/// Captures which class to use to provide specified service.
/// </summary>
/// <typeparam name="TService">The type of the service.</typeparam>
/// <typeparam name="TImplementation">The type of the implementation.</typeparam>
public void Register < TService, TImplementation >()
{
this.Container.Register< TService, TImplementation >();
}
/// <summary>
/// Captures <paramref name="instance"/> as the object to provide <typeparamref name="TService"/> for mocking.
/// </summary>
/// <typeparam name="TService">The type of the service.</typeparam>
/// <param name="instance">The instance.</param>
public void Register < TService > ( TService instance )
{
this.Container.Register( instance );
}
/// <summary>
/// Registers the given service creation delegate on the container.
/// </summary>
/// <typeparam name="TService">Service type.</typeparam>
public void Register < TService > ( Func< IResolve, TService > activator )
{
this.Container.Register( activator );
}
}
```