Last active
September 29, 2016 18:51
-
-
Save blairconrad/65c069daa92309793050bbe50272f8d1 to your computer and use it in GitHub Desktop.
SelfInitializedFakes
This file contains hidden or 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.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
namespace SelfInitializedFakes | |
{ | |
using FakeItEasy; | |
public static class SelfInitializedFake | |
{ | |
private static IDictionary<string, IEnumerable<SavedCall>> savedCallCatalogue = | |
new Dictionary<string, IEnumerable<SavedCall>>(); | |
public static TClass Create<TClass>(TClass actual, string savedCallKey) | |
{ | |
var fake = A.Fake<TClass>(); | |
IEnumerable<SavedCall> savedCalls; | |
savedCallCatalogue.TryGetValue(savedCallKey, out savedCalls); | |
if (savedCalls == null) | |
{ | |
var newSavedCalls = new List<SavedCall>(); | |
savedCallCatalogue[savedCallKey] = newSavedCalls; | |
SetupRecordingFake(actual, newSavedCalls, fake); | |
} | |
else | |
{ | |
LoadSavedCalls(savedCalls, fake); | |
} | |
return fake; | |
} | |
private static void LoadSavedCalls(IEnumerable<SavedCall> savedCalls, object fake) | |
{ | |
foreach (var savedCall in savedCalls) | |
{ | |
A.CallTo(fake).WithNonVoidReturnType() | |
.Where(call => call.Method == savedCall.Method) | |
.Returns(savedCall.ReturnValue); | |
} | |
} | |
private static void SetupRecordingFake<TClass>(TClass actual, IList<SavedCall> newSavedCalls, TClass fake) | |
{ | |
A.CallTo(fake).Invokes(call => | |
{ | |
call.Method.Invoke(actual, call.Arguments.ToArray()); | |
newSavedCalls.Add(new SavedCall {Method = call.Method}); | |
}); | |
A.CallTo(fake).WithNonVoidReturnType().ReturnsLazily(call => | |
{ | |
var result = call.Method.Invoke(actual, call.Arguments.ToArray()); | |
newSavedCalls.Add(new SavedCall {Method = call.Method, ReturnValue = result}); | |
return result; | |
}); | |
} | |
} | |
internal class SavedCall | |
{ | |
public MethodInfo Method { get; set; } | |
public object ReturnValue { get; set; } | |
} | |
} |
This file contains hidden or 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 SelfInitializedFakes.Tests | |
{ | |
using System; | |
using NUnit.Framework; | |
public class Tests | |
{ | |
[Test] | |
public void Test1() | |
{ | |
var fake = SelfInitializedFake.Create<AService>(new AService(), nameof(Test1)); | |
Assert.That(fake.GetCount("hippo"), Is.EqualTo(7)); | |
} | |
[Test] | |
public void Test2() | |
{ | |
var fake1 = SelfInitializedFake.Create<AService>(new AService(), nameof(Test2)); | |
Assert.That(fake1.GetCount("hippo"), Is.EqualTo(7)); | |
var fake2 = SelfInitializedFake.Create<AService>(new AService(), nameof(Test2)); | |
Assert.That(fake2.GetCount("hippo"), Is.EqualTo(7)); | |
} | |
} | |
public class AService | |
{ | |
private bool wasAlreadyCalled = false; | |
public virtual int GetCount(string id) | |
{ | |
if (wasAlreadyCalled) | |
{ | |
throw new InvalidOperationException("I was already called"); | |
} | |
wasAlreadyCalled = true; | |
return 7; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment