Donation towards Creating Safe Drinking Water
We have decided to participate with Jamie Cansdale and have donated 5 TypeMock Enterprise Licenses to go towards creating safe drinking water in Malawi Africa. You can see a link to the auction here.
Ever since I travelled in Africa a decade ago, it has been a special place for me and I am delighted to help out.
Here are some pictures of me in Africa: (1996/7)
A lion in the Safari, Massia Mara, Kenya
Massi keeping a distance from a Mamba snake.
Boy in Takawiri Island in Victoria Lake, seeing blue eyes for the first time in his life.
Ethiopian Friends from Shashamane, Ethiopia
In a hut on the Mulanji Mountains in Malawi
How to Stub with Conditional Expectations
Conditional Expectations is quite a powerful tool, that allows expectations to act differently according to the arguments passed to the mocked method.
This is very useful for Stubbing methods. Suppose there is a static method Customer.GetAge(string customerName) that needs to be isolated. But the tested code calls GetAge several times with different customerNames.
How can Mocked Customer.GetAge be mocked, to return a different age for each customerName? You guessed correctly Conditional Expectations.
Here is how we can set up GetAge() to return 27 for “Adam” and 22 for “Eve”.
Mock customerMock = MockManager.Mock(typeof(Customer)); customerMock.AlwaysReturn("GetAge",27).When("Adam"); customerMock.AlwaysReturn("GetAge",22).When("Eve");
Note the usage of When(). This is how Conditional Expectations are invoked. In the above example TypeMock will always return 27 when Customer.GetAge(“Adam”) is called and 22 when Customer.GetAge(“Eve”) is called.
In Natural Mocks our set up will look like this
using (RecordExpectations recorder = RecorderManager.StartRecording()) { Customer.GetAge("Adam"); recorder.Return(27).RepeatAlways.WhenArgumentsMatch(); Customer.GetAge("Eve"); recorder.Return(22).RepeatAlways.WhenArgumentsMatch(); }
You can probably see how using Conditional Expectation will help simplify mocking.
Conclusion
Here are the different ways that expectations can be setup in TypeMock.
- Always Expectations:
Methods mocked with Always will always be mocked, but are not verified (i.e. the method can be called zero or more times) - Invocation Expectations:
These methods are verified, and must be called for the test to pass - Conditional Always Expectation:
These Methods will not be verified and will be mocked ONLY when the arguments match those expected. (i.e. the method can be called zero or more times when the arguments match) - Conditional Invocation Expectation
These Methods are verified and must be called with the correct arguments for the test to pass.
The priorities are 4-3-2-1. So if there is both a Conditional Invocation Expectation (4) and an Invocation Expectations (2), the Conditional Invocation Expectation (4) will be used.
When to Stub and When to Mock
I was actually going to talk about how to stub using TypeMock but then I found that a little explanation is required.
If you haven’t read Mocks Aren’t Stubs by Martin Fowler, you should read it now. In short The difference between Mocks and Stubs is in the verification.
Stubs are fake objects that are required for a test but the arguments passed and the number of times each method is called is not significant for the test.
Mocks are also fake objects that are required for a test, but the test verifies that the mocked methods where actually called and the arguments passed where expected.
An Example Please
Now for an example: Suppose we have a Logger class that has a Log() method that is being called throughout our code. We might be testing the logic of the method and logging is not being tested. In this case we can stub out the Logger, as we don’t care if it is called and how many times.
But, if we are testing the logging mechanism of the method, we can mock the Logger and Verify that Log was called once with the correct arguments.
Here are the examples:
public void TestMethod() { Logger.Log("Entered TestMethod"); // do logic... } [Test] public void StubLogging() { Mock logMock = MockManager.Mock(typeof(Logger)); logMock.ExpectAlways("Log"); ... TestMethod(); } [Test] public void MockLogging() { Mock logMock = MockManager.Mock(typeof(Logger)); logMock.Expect("Log").Args("Entered TestMethod"); ... TestMethod(); MockManager.Verify(); }
In the first test StubLogging we don’t care if and whether Logger.Log() was called. So we use ExpectAlways to always fake the Log() method. ExpectAlways will not fail if the method was never called or was called, it will simply fake the method when it is called.
In the second test MockLogging we do want to verify that Logger.Log() was called ONE time with “Entered TestMethod” as the argument. Here we use ExpectCall to fake the Log() method. ExpectCall will fail if Log() was not called. (And when the mock is Strict it will fail if too many Log() methods where called).
We also verify that the argument that was passed to Log() is “Entered TestMethod” by using Args(). If a different argument was called the test will fail.
We must finish the test with a call to MockManager.Verify() to insure that the test fails if the expected methods where not called.
Summary
So here is a summary of the different API’s to use for stubs and mocks
| Stubs | Mocks |
| MockAll – all instances | Mock/MockObject – one instance |
| ExpectAlways – don’t care if the method was called | ExpectCall – Count and Verify the number of calls. |
| Don’t check arguments | Use Args() to verify arguments |
| No need to Verify | Always Verify() |
| Not Strict | Can be Strict |
For advanced Stubs you can use DynamicReturnValues, ConditionalExpectations and VerifyMode but that is for my next blog.
Recent Posts
- Unacceptable: Unit testing will take 20 years to catch on
- The 4 reasons why we DIDN’T choose Oslo
- Typemock Academy Launch
- The First Rule to Software Craftsmanship
- Goal-driven Development
Categories
- .NET Tests
- Agile
- Code Integrity
- Community
- Debugging
- Fun
- Management for Geeks
- Marketing
- Product
- Release
- Reviews
- SharePoint
- TDD
- Time Management
- Uncategorized
- Unit Tests
Archives
- May 2010
- April 2010
- March 2010
- February 2010
- December 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- December 2008
- November 2008
- August 2008
- July 2008
- May 2008
- April 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006





