When to MockObject?
In my previous post I showed how to mock future instances. Now we will see when to use MockObject.
What is the difference?
The difference is quite simple. But before we delve into it we should talk about the 2 objects that are associated with each mock.
Each mock has a controller that controls the behavior. This is done using the Mock type. Here we setup the Expectations and Validations. And each mock has the actual instance that is being mocked.
Using MockManager.Mock will mock a future instance.
Using MockManager.MockObject will immediately create a mocked instance. It is possible to access this instance using the mock.Object property. (Other mocking frameworks have only this option)
After creating a MockObject we can then pass this object as an argument to our tested method to inject the Mock.
[Test] public void MockObjectTest() { MockObject controlListener = MockManager.MockObject(typeof(MyListener)); MyListener mockedListener = (MyListener)controlListener.Object; // Setup expectation // inject our mocked object into our test Messages.Broadcast("I am alive",mockedListener); // Assertions... }
Note: There is no need for MyListener to be an interface, it could even be a sealed class!
What about interfaces?
When the mocked type (MyListener) is an interface or an abstract class TypeMock will create a new Type on-the-fly, that extends the mocked interface. This new object can then be passed to our tested code.
Mocks returning Mocks
A mocked expectation can return another mock. Here is an example
public class MyFactory { public MyListener GetListener() { // Get Listener through some complex external services } }
We can now setup the expectations that GetListener() will return a mocked MyListener.
[Test] public void MockObjectTest() { // mock future instance of MyFactory Mock factory = MockManager.Mock(typeof(MyFactory)); // create a MockObject of MyListener MockObject controlListener = MockManager.MockObject(typeof(MyListener)); MyListener mockedListener = (MyListener)controlListener.Object; // Setup expectation factory.ExpectAndReturn("GetListener",mockedListener); }
Summary
Here is a list of places where you should use MockObject.
- When a mocked object is passed to the tested method.
- When you need to mock an abstract class and interface.
- When a mocked method returns a mocked type
How To Isolate Future Instances
One of the benifits of testing with TypeMock is the ability to mock future objects. Future objects are instances that will be created w
ithin the tested code.
Here is an example:
private void InitializeComponent() { this.okButton = new System.Windows.Forms.Button(); this.cancelButton = new System.Windows.Forms.Button(); this.ignoreButton = new System.Windows.Forms.Button(); }
We create 3 new Buttons in this method. Suppose we want to isolate the tested code from the Windows.Forms component and mock those buttons.
Here is the easy way:
//Mock all Buttons Mock allButtonsMock = MockManager.MockAll(typeof(Button));
We mock all the Button objects (both future and past). This will mock all our buttons but we won’t be able to set expectations on a specific instance. So if we setup an expecation, the expected method will be mocked for the first instance that calls that specific method.
Here is how to have better control on the instances.
// Mock future instance of Button (okButton) Mock okButtonMock = MockManager.Mock(typeof(Button)); // Mock next instance of Button (cancelButton) Mock cancelButtonMock = MockManager.Mock(typeof(Button)); // Mock future instance of Button (ignoreButton) Mock ignoreButtonMock = MockManager.Mock(typeof(Button));
Now we can control each button seperatly, notice how the SEQUENCE of the Button constructors mathces the ORDER of the mock assignments. This is how TypeMock works, each time MockManager.Mock is called the next constuctor is mocked and all expectations are tied to the specific instance.
Using this and the Firing Events techniques we can simulate different button sequences.
// Mock ok Button Mock okButtonMock = MockManager.Mock(typeof(Button)); MockEvent clickOk = okButtonMock.ExpectAddEvent("Click"); // Mock cancel Button Mock cancelButtonMock = MockManager.Mock(typeof(Button)); MockEvent clickCancel = cancelButtonMock.ExpectAddEvent("Click"); // Mock ignore Button Mock ignoreButtonMock = MockManager.Mock(typeof(Button)); MockEvent clickIgnore = ignoreButtonMock.ExpectAddEvent("Click"); // run our code RunCodeThatCallsInitializeComponents(); // Test Button Clicks clickCancel.Fire(this,EventArgs.Empty);
Firing Events Made Easy
I have already posted about Firing Events (There is a “Fire Event” party pic to the right). Here is how to use reflective mocks to Fire Events.
Here is the example again:
public void Example() { Button button = new Button(); button.Click += new EventHandler(button_Click); } private void button_Click(object sender, EventArgs e) { // Do Somethings here }
Now we want to test that the Example class works correctly when the button is clicked. Here is how we mimic the Button click, by mocking the Button.
Test] public void TestThatExampleWorksWhenButtonClicked() { Mock buttonMock = MockManager.Mock(typeof(Button)); // expect Example to add an event (and keep a hook to the event) MockedEvent clickButton =buttonMock.ExpectAddEvent("Click"); // invoke our test method that registers to button.Click Example(); // Fire the event clickButton.Fire(this, EventArgs.Empty); // here we test that Example works correctly //… MockManager.Verify(); }
Notice the clickButton.Fire used to fire the Click event.
Cool
Tip: The Event must be subscribed before using Fire. Guess why?
How TypeMock Simplifies Unit Testing
Are you having trouble explaining TypeMock to your colleges?
We have added a small page that will help you.
See How Easily you can Love Your Job
If you are reading this you are probably the developer we are looking for.
TypeMock is expanding and we are looking for .NET developers who have a passion for Bleeding Edge Issues like Mocking (of course), Test Driven Development and Aspect Oriented Development.
We work in a dynamic environment and we have the infrastructure to support home offices for developers who require it.
Interested?
Send your resume to: jobs@typemock.com
New and Noteworthy – Version 3.6.1
We have released the patch version 3.6.1
Here are the highlights
Support Vista
TypeMock.NET now installs on Windows Vista RC2 Machines.
Install as Administrator and Enable Register Keys
Note: The Tracer does NOT work on Vista Machines.
Support Mocking Hidden Methods
It is possible to mock ‘hidden’ methods.
Mock overridden base methods with CallBase
Mock overloaded Static methods with CallStatic
Default Implementation of Dynamic Types
TypeMock.NET now creates a default implementation for interfaces and abstract methods. This allows natural property behavior and non strict method calls
This is turned off by default, call Strict=false or StrictFlags.ArbitraryMethodsAllowed to use this feature
Abstract Class Constructors
Abstract Type Constructors can now be invoked when creating a Dynamic Mock Object from an Abstract Type
Support ReSharper and dotTrace
We now support ReSharpers Unit Tests and dotTrace Profiler
Stictness
Natural Mocks now support controlling the Strictness of the mocks. See StrictFlags
Bug Fixes
- Version Mismatch Message Box doesn’t hang the application – (Build Server Support)
- Better Messages when using Code Coverage without Linking
- Fixed Bug with Dynamic Mocks with Generic Members
- Using Code Coverage From Visual Studio Doesn’t Require Disabling TypeMock
- Visual Studio 2003 Add In fixes
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

