Unit Testing Non Public Entities
Cpt S 321 Washington State University
NUnit and access modifiers
● NUnit does not allow us to test non-public methods
● So what do we do?
● Make all methods public? -> NO
● Test only public methods? -> NO
● Can we declare a ”friend” project? -> Yes, it will allow us to test internal methods
● Remember when we talked about Reflection? -> This is what we will use to test private methods
Testing internal methods
• A friend assembly is an assembly that can see the internal entities of
another assembly
• What we want is to declare our Test project (“TestProject”) as a friend
assembly to the project under test (“ProjectUnderTest”)
• How?: Edit the AssemblyInfo.cs of the project under test
(“ProjectUnderTest”) and add the following: [assembly: InternalsVisibleTo(“TestProject”)]
• That’s all!
Testing internal methods – let’s try it! (1/2)
1.
Create a class ClassToDemoTestingNonPublic in our HelloWorld project and define an internal method tripleThis as follows:
// Method that takes an integer value and returns the value tripled. internal static int tripleThis(int aNumber)
If you haven’t done so already, create a NUnit test project
HelloWorldTests
In the assembly info file of HelloWorld give access to internal entities that are declared in HelloWorld to HelloWorldTests through “InternalsVisibleTo” (see previous slide)
2. 3.
Testing internal methods – let’s try it! (2/2)
4. In HelloWorldTests, write test cases to test tripleThis • What types of test cases do we need?
• How many test cases do we need?
Testing private methods
• We will use Reflection in our test class ClassToDemoTestingNonPublicTest
• We will declare an object of the class under test
• We will implement a method to look up a method declared in the class
under test by passing the name of the method as a string
• We will invoke the retrieved method and test it as we typically do
Testing private methods – let’s try it!
class ClassToDemoTestingNonPublic
{
{
return aNumber; }
// … }
// …
private int privateInstanceMethod(int aNumber)
Testing private methods – let’s try it!
public class ClassToDemoTestingNonPublicTest
{
private ClassToDemoTestingNonPublic objectUnderTest =
new ClassToDemoTestingNonPublic();
private MethodInfo GetMethod(string methodName){ if (string.IsNullOrWhiteSpace(methodName))
Assert.Fail(“methodName cannot be null or whitespace”);
var method = this.objectUnderTest.GetType() .GetMethod(methodName,
BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
if (method == null)
Assert.Fail(string.Format(“{0} method not found”, methodName));
return method; }
Testing private methods – let’s try it! (cont.)
// Still in ClassToDemoTestingNonPublicTest public void TestMyPrivateInstanceMethod() {
// Retrieve the method that we want to test using reflection MethodInfo methodInfo = this.GetMethod(“privateInstanceMethod”);
// Test the method by calling the MethodBase.Invoke method Assert.AreEqual(5,
methodInfo.Invoke(objectUnderTest, // the object on which
// we are invoking the method
new object[] { 5 } // the list of parameters (in our case, just one)
)); }
Are we done?
• Not really
• What is the problem with our current implementation and how can
we fix it?
• Hint: Check the Type.GetMethod Method
• Fix it!