How did we do that?!!
If you have read my previous post about the TypeMock Test Attributes you probably have noticed that the attributes are test framework agnostic!
So how did we do that?
We tried to add our attributes using implementing the hooks of each framework. But we found this way to be unstable:
- mbUnit is the easiest framework to extend, it is build with extensions in mind, but the extensions are version specific
- nUnit has just started supporting extensions and the system is fragile, the extension system requires deploying to each nunit installation (and TestDriven.NET too) and needs to be redistributed for each nunit version as the extensions are version specific.
- msTest (the Visual Studio Team System) currently has no means to extend and add attributes.
Then we remembered that TypeMock has an AOP framework. We can inject the Attributes! This is what we did.
We spiked and wrote the following code
[TestFixture] public class Spike { [SetUp] public void InjectVerifyMocks() { foreach (MethodInfo info in this.GetType().GetMethods()) { if (info.GetCustomAttributes(typeof(VerifyMeAttribute), false).Length > 0) { Mock m = MockManager.MockAll(this.GetType()); MethodInfo keepInfo = info; m.AlwaysReturn(info.Name, new DynamicReturnValue( delegate(object[] p, object c) { keepInfo.Invoke(c, p); MockManager.Verify(); return null; // void method })); } } } [Test] [VerifyMe] public void SpikeTest() { Mock m = MockManager.Mock<MockedClass>(); m.ExpectAndReturn("Method",10); } }
Ok, so what are we doing here?
In the setup we are scanning all the methods for a custom attribute. When we find such a method we mock ourselves!!! and change the behavior of our methods to return a dynamic return.
The dynamic return will call ourselves again!!! (via reflection) and then verify the mocks.
When we run the test (in all frameworks) it fails with VerifyException.
TestCase ‘Spike.SpikeTest‘ failed: TypeMock.VerifyException : TypeMock Verification: Method MockedClass.Method() has 1 more expected calls
This works because while we are in the DynamicReturnValue Delegate, TypeMock is turned off and no methods are mocked. So we don’t recursively call ourselves, but on the other hand this means that our mocks are all turned off.
This was just a spike to prove that it was possible, it took more time to implemented the extension system that will work for all testing frameworks.
I will publish how to extend and create your own attributes when we release the beta version.










Leave a Reply