9

I have a a static class which has a private variable.

private static Dictionary<strng, string> items = new Dictionary<string, string>();

Many public methods of the class access this dictionary object. Now I want to write NUNit test class (in different library). How can I test this private variable?

Learner
  • 4,661
  • 9
  • 56
  • 102

4 Answers4

9

I wouldn't get into the discussion of weather you should or not test internal methods of an internal class. You can expose your internal methods/properties/classes/etc. to an external library, by using the InternalsVisibleToAttribute attribute.

For example, if your unit testing library is named MyUnitTestsLibrary, just add the following in the AssemblyInfo.cs file of your project (the one being tested).

[assembly:InternalsVisibleTo("MyUnitTestsLibrary")]

This will make the MyUnitTestsLibrary library a friend library of your project to be tested and exposing all of it's internal stuff so you can do unit tests.

Miljenko Barbir
  • 1,193
  • 1
  • 11
  • 32
6

I know that the question is about NUnit and I don't want to argue whether it's a good or bad practice to test private members. The fact is that it's sometimes necessary, especially when you have to deal with legacy or poorly designed code that you can't refactor.

So I would like to mention that Gallio/MbUnit provides a light API called Mirror to ease testing with private type members.


Example: the following test sample invokes the private method named SomePrivateMethod on the foo instance.

[Test]
public void SampleTest()
{
   var foo = new Foo();
   int actual = Mirror.ForObject(foo)["SomePrivateMethod"].Invoke();
   Assert.AreEqual(123, actual);
}
Yann Trevin
  • 3,823
  • 1
  • 30
  • 32
  • 2
    MSTest offers the same functionality via its Accessor things. But it is still meaningless to unit test, as you should test against the unit, not its inner implementation. – Lex Li Dec 20 '10 at 11:09
3

You don't test private variables, you test class' behaviour.

This mean that you should test only the class' public interface.

See also this question.

Community
  • 1
  • 1
Simone
  • 11,655
  • 1
  • 30
  • 43
  • Thank you for your answer. However, I find many people supporting both sides of debate on 'If only public interfaces should be tested or private methods as well?' So if at all I need to test private variable, is there any way out?.. – Learner Dec 20 '10 at 11:24
  • Yes, you can since with reflection - for example - you can bypass C# encapsulation. Maybe Yann's answer could help you out. Anyway, if I was you, I'd look for another way. – Simone Dec 20 '10 at 11:28
  • Downvoted: Yann's response is better, this is unhelpful and myopic, assuming the author's view is the only opinion. – Quango May 15 '13 at 13:08
2

When unit testing you should test the public interface, not the private implementation. Check that the interface behaves as expected when you perform operations on it, without checking the Dictionary itself. That way if you decide in future to replace the Dictionary with a different data structure, you won't break all your tests.

Jackson Pope
  • 14,520
  • 6
  • 56
  • 80
  • Thank you for your answer. However, I find many people supporting both sides of debate on 'If only public interfaces should be tested or private methods as well?' So if at all I need to test private variable, is there any way out?. – Learner Dec 20 '10 at 11:25
  • If you _really_ need to do it, try Yann's method. But the thinking behind it is that the only way your class can interact with the rest of your system is through its public interface, so that's all you need to test. How your class chooses to implement that interface is up to you, _as long as you meet your obligations through the public interface_. Test that thoroughly and tests on your implementation are unnecessary and brittle (will break easily with changes). – Jackson Pope Dec 20 '10 at 11:33