Andrew Stopford's Weblog

poobah

Sponsors

News

Articles

Family

Old Blogs

Testing private methods, new to MbUnit 2.4.

Update: This is available in build 2.4.28 onwards

I know that some consider testing private methods wrong (its a topic of some debate) but others find it a useful and wanted feature and frameworks like TestNG and MSTest let you do this if you want to. Ben Hall contributed this feature which builds on using Reflection to expose private methods and builds on the work done by Chris Holmes and Tim Stall. This is the first addition to the new mbunit.framework.2.0.dll that will ship with 2.4, to use this functionality you will need import that dll along with the standard mbunit.framework.dll file. So taken a simple example file

  1. public class TestSample
  2. {
  3. private int counter = 0;
  4. private bool accessed = false;
  5. private void IncCounter()
  6. {
  7. counter++;
  8. }
  9. private void SetAsAccessed()
  10. {
  11. accessed = true;
  12. }
  13. }

We could run a test as follows

  1. using MbUnit.Framework.Reflection;
  2. [TestFixture]
  3. public class ReflectorStaticTests
  4. {
  5. TestSample sampleObject;
  6. [SetUp]
  7. public void Setup()
  8. {
  9. sampleObject = new TestSample();
  10. }
  11. [Test]
  12. public void RunPrivateMethodOnObjectUsingStatic()
  13. {
  14. Reflector.RunNonPublicMethod(sampleObject, "IncCounter");
  15. }
  16. [Test]
  17. public void CheckPrivateValueOnObjectUsingStatic()
  18. {
  19. object result = Reflector.GetNonPublicVariable(sampleObject, "counter");
  20. Assert.AreEqual(0, (int)result);
  21. }
  22. [Test]
  23. public void RunPrivateMethodAndCheckPrivateValueUsingStatic()
  24. {
  25. int execute = 3;
  26. for (int i = 0; i < execute; i++)
  27. Reflector.RunNonPublicMethod(sampleObject, "IncCounter");
  28. object result = Reflector.GetNonPublicVariable(sampleObject, "counter");
  29. Assert.AreEqual(execute, (int)result);
  30. }
  31. }

This example calls the methods by passing the instance you wish to reflect (in a static fasion) but the code also allows you do the following.

  1. [TestFixture]
  2. public class InstanceTests
  3. {
  4. TestSample sampleObject;
  5. Reflector reflect;
  6. [SetUp]
  7. public void Setup()
  8. {
  9. sampleObject = new TestSample();
  10. reflect = new Reflector(sampleObject);
  11. }
  12. [Test]
  13. public void RunPrivateMethodOnObjectUsingInstance()
  14. {
  15. reflect.RunPrivateMethod("IncCounter");
  16. }
  17. [Test]
  18. public void CheckPrivateValueOnObjectUsingInstance()
  19. {
  20. object result = reflect.GetPrivateVariable("counter");
  21. Assert.AreEqual(0, (int)result);
  22. }
  23. [Test]
  24. public void RunPrivateMethodAndCheckPrivateValueUsingInstance()
  25. {
  26. int execute = 3;
  27. for (int i = 0; i < execute; i++)
  28. reflect.RunPrivateMethod("IncCounter");
  29. object result = reflect.GetPrivateVariable("counter");
  30. Assert.AreEqual(execute, (int)result);
  31. }
  32. }

Here the reflector instance is passed a object instance and methods are called on that instance, it saves you having to pass object instances around but it's really down to preferance.

Posted: Dec 20 2006, 02:07 PM by andrewstopford | with no comments
Filed under: ,

Comments

No Comments