OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #region | |
6 | |
7 using System; | |
8 using System.Collections.Generic; | |
9 | |
10 #endregion | |
11 | |
12 namespace Google.MsAd7.BaseImpl.TestUtils { | |
13 /// <summary> | |
14 /// This class provides a simple record-replay mock. It lives in MsAd7 | |
15 /// because this is the lowest-level C# project. | |
16 /// </summary> | |
17 public class MockBase { | |
18 /// <summary> | |
19 /// Resets the state of the Mock. This exists so that unit testing | |
20 /// functionality can be factored in such a way that each function that | |
21 /// has to mock transactions does not have to know about the transactions | |
22 /// tested by any other functions involved. | |
23 /// </summary> | |
24 public void Reset() { | |
25 expectedCalls_ = new List<MockEntry>(); | |
26 index_ = 0; | |
27 } | |
28 | |
29 /// <summary> | |
30 /// Records a call with one argument to be expected by the mock. The | |
31 /// calls will be expected in the order in which they are recorded. | |
32 /// </summary> | |
33 /// <typeparam name = "TArgType">The type of the call's argument. | |
34 /// </typeparam> | |
35 /// <param name = "functionName">The name of the function to be called. | |
36 /// </param> | |
37 /// <param name = "functionArg">The argument of the function to be called. | |
38 /// </param> | |
39 /// <param name = "returnValue">The value to be returned when this mock-call | |
40 /// occurs.</param> | |
41 public void RecordCall<TArgType>(string functionName, | |
42 TArgType functionArg, | |
43 object returnValue) { | |
44 var args = new List<object>(); | |
45 args.Add(functionArg); | |
46 AddCall(functionName, args, returnValue); | |
47 } | |
48 | |
49 /// <summary> | |
50 /// Records a call with no arguments to be expected by the mock. The | |
51 /// calls will be expected in the order in which they are recorded. | |
52 /// </summary> | |
53 /// <param name = "functionName">The name of the function to be called. | |
54 /// </param> | |
55 /// <param name = "returnValue">The value to be returned when this mock-call | |
56 /// occurs.</param> | |
57 public void RecordCall(string functionName, | |
58 object returnValue) { | |
59 AddCall(functionName, new List<object>(), returnValue); | |
60 } | |
61 | |
62 #region Private Implementation | |
63 | |
64 private List<MockEntry> expectedCalls_ = new List<MockEntry>(); | |
65 private int index_; | |
66 | |
67 #endregion | |
68 | |
69 #region Private Implementation | |
70 | |
71 /// <summary> | |
72 /// Adds a call to the queue. This function is argument and type agnostic | |
73 /// so it can be used by all the RecordCall functions. | |
74 /// </summary> | |
75 /// <param name = "functionName">The name of the function to be called. | |
76 /// </param> | |
77 /// <param name = "functionArgs">Any arguments to be expected for the | |
78 /// function call, as a list of objects.</param> | |
79 /// <param name = "returnValue">The value to be returned when this mock-call | |
80 /// occurs.</param> | |
81 private void AddCall(string functionName, | |
82 List<object> functionArgs, | |
83 object returnValue) { | |
84 var mockEntry = new MockEntry { | |
85 FunctionName = functionName, | |
86 FunctionArgs = functionArgs, | |
87 ReturnValue = returnValue, | |
88 }; | |
89 expectedCalls_.Add(mockEntry); | |
90 } | |
91 | |
92 #endregion | |
93 | |
94 /// <summary> | |
95 /// Checks the validity of a call that has been made. This function is to | |
96 /// be invoked by the mock when any of its one-argument functions are | |
97 /// called and need to be verified. | |
98 /// </summary> | |
99 /// <typeparam name = "TArgType">The type of the argument to be checked. | |
100 /// </typeparam> | |
101 /// <typeparam name = "TReturnType">The type to cast the return value to. | |
102 /// </typeparam> | |
103 /// <param name = "aName">The name of the function to be checked.</param> | |
104 /// <param name = "functionArg">The argument with which the function got | |
105 /// called.</param> | |
106 /// <returns>The stored return value for this function call if all the | |
107 /// checks pass.</returns> | |
108 protected TReturnType CheckCall<TArgType, TReturnType>( | |
109 string aName, TArgType functionArg) { | |
110 if (index_ >= expectedCalls_.Count) { | |
111 throw new MockException( | |
112 "Got called when no calls were expected."); | |
113 } | |
114 var mockEntry = expectedCalls_[index_]; | |
115 if (mockEntry.FunctionName != aName || | |
116 mockEntry.FunctionArgs.Count != 1) { | |
117 throw new MockException( | |
118 "Mock got called with the wrong function signature."); | |
119 } | |
120 if (!(mockEntry.FunctionArgs[0] is TArgType)) { | |
121 throw new MockException( | |
122 "Mock got called with the wrong argument type."); | |
123 } | |
124 var expectedArg = (TArgType) mockEntry.FunctionArgs[0]; | |
125 if (!Equals(expectedArg, functionArg)) { | |
126 throw new MockException( | |
127 "Mock got called with the wrong argument value."); | |
128 } | |
129 if (!(expectedCalls_[index_].ReturnValue is TReturnType)) { | |
130 throw new MockException( | |
131 "Mock got called with the wrong return type."); | |
132 } | |
133 return (TReturnType) expectedCalls_[index_++].ReturnValue; | |
134 } | |
135 | |
136 /// <summary> | |
137 /// Checks the validity of a call that has been made. This function is to | |
138 /// be invoked by the mock when any of its one-argument functions are | |
139 /// called and need to be verified. | |
140 /// </summary> | |
141 /// <typeparam name = "TReturnType">The type to cast the return value to. | |
142 /// </typeparam> | |
143 /// <param name = "aName">The name of the function to be checked.</param> | |
144 /// <returns>The stored return value for this function call if all the | |
145 /// checks pass.</returns> | |
146 protected TReturnType CheckCall<TReturnType>(string aName) { | |
147 if (index_ >= expectedCalls_.Count) { | |
148 throw new MockException( | |
149 "Got called when no calls were expected."); | |
150 } | |
151 var mockEntry = expectedCalls_[index_]; | |
152 if (mockEntry.FunctionName != aName || | |
153 mockEntry.FunctionArgs.Count != 0) { | |
154 throw new MockException( | |
155 "Mock got called with the wrong function signature."); | |
156 } | |
157 if (!(expectedCalls_[index_].ReturnValue is TReturnType)) { | |
158 throw new MockException( | |
159 "Mock got called with the wrong return type."); | |
160 } | |
161 return (TReturnType) expectedCalls_[index_++].ReturnValue; | |
162 } | |
163 | |
164 #region Nested type: MockEntry | |
165 | |
166 protected class MockEntry { | |
167 public string FunctionName; | |
168 public List<object> FunctionArgs; | |
169 public object ReturnValue; | |
170 } | |
171 | |
172 #endregion | |
173 | |
174 #region Nested type: MockException | |
175 | |
176 public class MockException : Exception { | |
177 public MockException(string error) : base(error) {} | |
178 } | |
179 | |
180 #endregion | |
181 } | |
182 } | |
OLD | NEW |