Here is a little Mock super class we've used in one of our projects. It may come in handy when you don't want to bring out the big Mock frameworks...
(credits go to TimV for punching up this code)
/// <summary>/// A representation of expected method calls/// </summary>public class MethodCall
{ /// <summary> /// Creates a new <see cref="MethodCall"/> instance. /// </summary> /// <param name="methodName">Name of the method.</param> /// <param name="returnValue">The return value of the method, can be null in case of a void return type or an actual expected null</param> /// <param name="parameters">Parameters.</param> public MethodCall
(string methodName,
object returnValue,
object[] parameters
) { _methodName = methodName;
_parameters = parameters;
_returnValue = returnValue;
} private object _returnValue;
private string _methodName;
private object[] _parameters;
/// <summary> /// Gets or sets the name of the method of the methodcall. /// </summary> /// <value></value> public string MethodName
{ get
{ return _methodName;
} set
{ _methodName = value;
} } /// <summary> /// Gets or sets the parameters of the methodcall. /// </summary> /// <value></value> public object[] Parameters
{ get
{ return _parameters;
} set
{ _parameters = value;
} } /// <summary> /// Gets or sets the parameters of the methodcall. /// </summary> /// <value></value> public object ReturnValue
{ get
{ return _returnValue;
} set
{ _returnValue = value;
} }}/// <summary>/// This is the actual mock super class. Any mock object should inherit from this class./// </summary>public abstract
class MockBase
{ /// <summary> /// Creates a new <see cref="MockBase"/> instance. /// </summary> protected MockBase
() { _numberOfExpectedCalls =
0;
_expectedMethodCalls =
new SortedList
();
} private int _numberOfExpectedCalls;
private int _numberOfActualCalls;
private SortedList _expectedMethodCalls;
/// <summary> /// Expect a method call with a certain number of parameters. /// The order of setting these expectations is important. /// </summary> /// <param name="methodName">The name of the method that is expected to be called.</param> /// <param name="returnValue">The value the mock object should return when the expected /// method is actually called, can be null in case of a void return type or an actual expected null</param> /// <param name="parameters">The expected parameters of the method call</param> protected virtual void ExpectCall
(string methodName,
object returnValue,
params object[] parameters
) { ExpectCall
(new MethodCall
(methodName, returnValue, parameters
));
} /// <summary> /// Expect a method call with a certain number of parameters. /// The order of setting these expectations is important. /// </summary> /// <param name="methodCall">Method call.</param> protected virtual void ExpectCall
(MethodCall methodCall
) { _expectedMethodCalls.
Add(++_numberOfExpectedCalls, methodCall
);
} /// <summary> /// Simulates a method call on the mock object. An assertion is done to see if the call was expected. /// </summary> /// <param name="methodName">The name of the method that is called</param> /// <param name="parameters">The parameters to pass with the simulated method call</param> protected virtual object MethodCalled
(string methodName,
params object[] parameters
) { int currentCallNumber = ++_numberOfActualCalls;
MethodCall expectedMethodCall =
(MethodCall
)_expectedMethodCalls
[currentCallNumber
];
Assert.
IsNotNull(expectedMethodCall,
"The expected method : " + methodName +
" was called but not expected !");
Assert.
AreEqual(expectedMethodCall.
MethodName, methodName,
"Expected method " + expectedMethodCall.
MethodName +
" to be called as call number " + currentCallNumber +
" instead of " + methodName
);
for (int i =
0; i < parameters.
Length; i++
) { if (expectedMethodCall.
Parameters[i
] !=
null) { Assert.
AreEqual(expectedMethodCall.
Parameters[i
], parameters
[i
],
"Parameters used in " + methodName +
" call number " + currentCallNumber +
" differ from the expected parameters || " + expectedMethodCall.
Parameters[i
].
GetType().
Name +
" actual type : " + parameters
[i
].
GetType().
Name);
} } _expectedMethodCalls.
Remove(currentCallNumber
);
return expectedMethodCall.
ReturnValue;
} /// <summary> /// Determine if the mock is expecting any method calls. This should always be false on the end of a unit test. /// </summary> /// <returns> /// true if there are expected methods that have not been called yet, otherwise false. /// </returns> public virtual bool IsWaitingForMethodCalls
() { return (_expectedMethodCalls.
Count >
0);
}}