Evolution of a hand rolled fake
I usually hand roll my own fake objects for my tests. They have always looked a lot like what Stubs generate. I just think that it's so cheap to create them that I don't even need Stubs. In this series I'll assume an interface that looks like this:
1: interface ITheInterface
2: {
3: void DoSomething(int x);
4: int ComputeSomething(int a, int b);
5: }
When I first started to hand roll my fakes it looked something like this:
6: private class FakeTheInterface : ITheInterface
7: {
8: public Action<int> DoSomethingHandler { get; set; }
9: public Func<int, int, int> ComputeSomethingHandler { get; set; }
10:
11: public void DoSomething(int x)
12: {
13: if (DoSomethingHandler == null)
14: {
15: Assert.Fail("Unexpected call to DoSomething");
16: }
17:
18: DoSomethingHandler(x);
19: }
20:
21: public int ComputeSomething(int a, int b)
22: {
23: if (ComputeSomethingHandler == null)
24: {
25: Assert.Fail("Unexpected call to ComputeSomething");
26: }
27:
28: return ComputeSomethingHandler(a, b);
29: }
30: }
Which gave you a test that looked something like this:
31: [TestMethod]
32: public void UsingFake1()
33: {
34: var thing = new FakeTheInterface();
35: thing.ComputeSomethingHandler = (a, b) => 42;
36: Assert.AreEqual(42, thing.ComputeSomething(0, 0));
37: }
After a while I realized that I could make the fake a little nicer by doing this:
38: private class FakeTheInterface : ITheInterface
39: {
40: public Action<int> DoSomethingHandler { get; set; }
41: public Func<int, int, int> ComputeSomethingHandler { get; set; }
42:
43: public void DoSomething(int x)
44: {
45: Assert.IsNotNull(DoSomethingHandler,
46: "Unexpected call to DoSomething");
47: DoSomethingHandler(x);
48: }
49:
50: public int ComputeSomething(int a, int b)
51: {
52: Assert.IsNotNull(ComputeSomethingHandler,
53: "Unexpected call to ComputeSomething");
54: return ComputeSomethingHandler(a, b);
55: }
56: }
But once in a while I came across an interface with a method that had a method like FooHandler. "FooHandlerHandler" is just very confusing. Recently I tried a different approach that looks like this:
57: private class FakeTheInterface : ITheInterface
58: {
59: private Action<int> doSomething =
60: x => Assert.Fail("Unexpected call to DoSomething({0}).", x);
61:
62: private Func<int, int, int> computeSomething =
63: (a, b) =>
64: {
65: Assert.Fail(
66: "Unexpected call to ComputeSomething({0}, {1}).",
67: a, b);
68: return 0;
69: };
70:
71: public FakeTheInterface(
72: Action<int> DoSomething = null,
73: Func<int, int, int> ComputeSomething = null)
74: {
75: doSomething = DoSomething ?? doSomething;
76: computeSomething = ComputeSomething ?? computeSomething;
77: }
78:
79: public void DoSomething(int x)
80: {
81: doSomething(x);
82: }
83:
84: public int ComputeSomething(int a, int b)
85: {
86: return computeSomething(a, b);
87: }
88: }
Note that I abuse the naming guidelines for arguments in order to make it consistent with the method name. A test using this fake looks like this:
89: [TestMethod]
90: public void UsingFake3()
91: {
92: var thing = new FakeTheInterface(
93: ComputeSomething: (a, b) => 42);
94: Assert.AreEqual(42, thing.ComputeSomething(0, 0));
95: }
So far I'm happy with this evolution. The only potential problem I see is if I need to replace the implementation half way through a test, but that can still be achieved by having a seperate variable in the test that I use and then change. So all in all it feels like this last evolution will be used (by me) for a while. Suggestions on improvements welcome!