Last active
August 1, 2016 22:30
-
-
Save hlaueriksson/ffd7e5b3f6b9074d4643e57e4f3f7ae5 to your computer and use it in GitHub Desktop.
2016-05-30-automocked-base-class-for-nunit-tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace ConductOfCode | |
{ | |
public class HelloWorld | |
{ | |
private readonly IFoo _foo; | |
private readonly IBar _bar; | |
public HelloWorld(IFoo foo, IBar bar) | |
{ | |
_foo = foo; | |
_bar = bar; | |
} | |
public string GetMessage() | |
{ | |
return _foo.GetFoo() + _bar.GetBar(); | |
} | |
} | |
public interface IFoo | |
{ | |
string GetFoo(); | |
} | |
public interface IBar | |
{ | |
string GetBar(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using ConductOfCode.Fakes; | |
using Moq; | |
using NUnit.Framework; | |
using Should; | |
namespace ConductOfCode.Tests.Given_HelloWorld_WithSubject | |
{ | |
public class When_GetMessage : WithSubject<HelloWorld> | |
{ | |
[SetUp] | |
public void SetUp() | |
{ | |
The<IFoo>().Setup(x => x.GetFoo()).Returns("Hello"); | |
With<IBar>(x => x.GetBar() == ", World!"); | |
} | |
[Test] | |
public void Should_invoke_IFoo_GetMessage() | |
{ | |
Subject.GetMessage(); | |
The<IFoo>().Verify(x => x.GetFoo()); | |
} | |
[Test] | |
public void Should_invoke_IBar_GetMessage() | |
{ | |
Subject.GetMessage(); | |
The<IBar>().Verify(x => x.GetBar(), Times.Once); | |
} | |
[Test] | |
public void Should_return_a_concatenated_string_with_messages_from_IFoo_and_IBar() | |
{ | |
Subject.GetMessage().ShouldEqual("Hello, World!"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq.Expressions; | |
using Moq; | |
using Moq.AutoMock; | |
using NUnit.Framework; | |
namespace ConductOfCode.Fakes | |
{ | |
/// <summary> | |
/// Base class that adds auto mocking/faking to NUnit. | |
/// </summary> | |
/// <typeparam name="TSubject"> | |
/// The subject of the specification. This is the type that is created by the specification for you. | |
/// </typeparam> | |
public abstract class WithSubject<TSubject> where TSubject : class | |
{ | |
private AutoMocker _mocker; | |
private TSubject _subject; | |
/// <summary> | |
/// Gives access to the subject under specification. On first access | |
/// the spec tries to create an instance of the subject type by itself. | |
/// </summary> | |
protected TSubject Subject => _subject ?? (_subject = _mocker.CreateInstance<TSubject>()); | |
[SetUp] | |
public void Setup() | |
{ | |
_mocker = new AutoMocker(); | |
} | |
[TearDown] | |
public void TearDown() | |
{ | |
_subject = null; | |
} | |
/// <summary> | |
/// Creates a fake of the type specified by <typeparamref name="TInterfaceType" />. | |
/// This method reuses existing instances. If an instance of <typeparamref name="TInterfaceType" /> | |
/// was already requested it's returned here. (You can say this is kind of a singleton behavior) | |
/// Besides that, you can obtain a reference to injected instances/fakes with this method. | |
/// </summary> | |
/// <typeparam name="TInterfaceType">The type to create a fake for. (Should be an interface or an abstract class)</typeparam> | |
/// <returns> | |
/// An instance implementing <typeparamref name="TInterfaceType" />. | |
/// </returns> | |
protected Mock<TInterfaceType> The<TInterfaceType>() where TInterfaceType : class | |
{ | |
return _mocker.GetMock<TInterfaceType>(); | |
} | |
/// <summary> | |
/// Configures the specification to use the specified instance for <typeparamref name="TInterfaceType" />. | |
/// </summary> | |
/// <typeparam name="TInterfaceType">The type to inject.</typeparam> | |
/// <param name="instance">The instance to inject.</param> | |
protected void With<TInterfaceType>(TInterfaceType instance) | |
{ | |
_mocker.Use(instance); | |
} | |
/// <summary> | |
/// Configures the specification to use the specified mock for <typeparamref name="TInterfaceType" />. | |
/// </summary> | |
/// <typeparam name="TInterfaceType">The type to inject.</typeparam> | |
/// <param name="mock">The mock to inject.</param> | |
protected void With<TInterfaceType>(Mock<TInterfaceType> mock) where TInterfaceType : class | |
{ | |
_mocker.Use(mock); | |
} | |
/// <summary> | |
/// Configures the specification to setup a mock with specified behavior for <typeparamref name="TInterfaceType" />. | |
/// </summary> | |
/// <typeparam name="TInterfaceType">The type to inject.</typeparam> | |
/// <param name="setup">The behavior to inject.</param> | |
protected void With<TInterfaceType>(Expression<Func<TInterfaceType, bool>> setup) where TInterfaceType : class | |
{ | |
_mocker.Use(setup); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment