Vadim's Weblog

Never stop learning.

Testing Non-Public members with MbUnit (Part II).

Posted by Vadim on April 29, 2007

Earlier this month I talked about how to test non-public members with MbUnit. Well there’s an interesting discussion on MbUnit group. As a result a new code was written.

Following methods are marked as obsolete. My guess is that these methods are going to be gone completely in version 3.

Old Method New Method
GetNonPublicField GetField
GetNonPublicVariable GetField
GetNonPublicProperty GetProperty
RunPrivateMethod InvokeMethod
RunNonPublicMethod InvokeMethod

There’re also new methods:
SetField – Sets field value.
SetProperty – Sets property value.

Thanks to Jeff who pointed out that Reflector didn’t have these methods. He also mentioned that method names between static and instance implementation are inconsistent. This also was corrected.

Let’s create SampleClass:


public class SampleClass
{
public string publicString = "MbUnit Rocks!!!";
private DateTime privateDateTime = DateTime.Today;

    internal DateTime InternalProperty
{
get { return privateDateTime; }
set { privateDateTime = value; }
}

    private static int Add(int x, int y)
{
return x + y;
}
}

Here an example how we can create tests for SampleClass:



TestSample _sampleObject;
Reflector _reflect;

[TestFixtureSetUp]
public void Init()
{
_sampleObject = new SampleClass();
_reflect = new Reflector(_sampleObject);
}

[Test]
public void GetPublicField()
{
Assert.AreEqual(“MbUnit Rocks!!!”, _reflect.GetField(“publicString”));
}

[Test]
public void SetNonPublicProperty()
{
string propertyName = “InternalProperty”;
DateTime dt = new DateTime(2008, 1, 1);
_reflect.SetProperty(propertyName, dt);
Assert.AreEqual(dt, _reflect.GetProperty(propertyName));
}

[Test]
public void StaticPrivateMethod()
{
Assert.AreEqual(7, _reflect.InvokeMethod(“Add”, 1, 6));
}

I mentioned before that static and instance methods now have consistent names.
You can implement StaticPrivateMethod test like this using static implementation of InvokeMethod(..).


[Test]
public void StaticPrivateMethod()
{
Assert.AreEqual(7, Reflector.InvokeMethod(new SampleClass(), "Add", 1, 6));
}

Here’s another of Jeff’s suggestions:

Indicating public vs. non-public is useful for documentation purposes.

Once again, because of Jeff’s suggestion we have AccessModifier enum type and using it we can specify if we want to access public, static, or non-public member. In examples above we didn’t use AccessModifier. It means that Reflector will invoke method or access field or property as long as an object has implementation for it.

In the example below we are trying to test Add method that has private static modifier. However, if Add method wasn’t static or was public, an assirtion would happen in our test.


[Test]
public void StaticPrivateMethod()
{
Assert.AreEqual(7, _reflect.InvokeMethod(AccessModifier.Static | AccessModifier.NonPublic,,"Add",1,6));
}

It’s a new code that was checked in; however, it has not been built yet. These and some other new features should be available in a next MbUnit build.
kick it on DotNetKicks.com

About these ads

7 Responses to “Testing Non-Public members with MbUnit (Part II).”

  1. Julian said

    Good job :)

  2. [...] internals members with InternalsVisibleTo attribute. I posted previously about testing non-public members with MbUnit.  I recently found out about InternalsVisibleTo [...]

  3. Max said

    Do private methods with out parameters work the same way?

  4. Vadim said

    Max,

    Private methods with out parameters are goint to work the same way.

  5. Stefan said

    Hallo,

    I tried to test private methods with out parameters but mbunit always throws a System.NullreferenceException.

    If i tried it without the out modifier the test always worked fine.

    Here is the method:
    private bool ByteArrayToInt16(byte[] byteArray, out Int16 returnInt)

    and this it How I tried to test is:

    ClassCRC16 crc16;
    Reflector _reflector;

    crc16 = new ClassCRC16();
    _reflector = new Reflector(crc16);

    object[] args = new object[] { byteArray, null};
    _reflector.InvokeMethod(“ByteArrayToInt16″, args);

    The last line always “creates” this exception.

    What is wrong? Any idea?

  6. Vadim said

    Stefan,
    You have NullReferenceException because you’re assigning null to Int16.

    Try to use 0 instead of null:

    object[] args = new object[] { byteArray, 0};

  7. Stefan said

    Hi Vadim,
    if I replace ‘null’ by ’0′ MbUnit says ‘Fail to find ByteArrayToInt16 Method …).
    What is wrong?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: