PrivateObject function does not return parameter

I am trying to test private methods in a Unit test project. So far, everything is going fine, but I hit a beat when I have to test a method with an out parameter. Signature for this method:

private bool GotSSI(out SSI ssi, RSI rsi) { ~code omitted~ } 

And unittest (the part that doesn't work) looks like this:

 SSI ssi = null; object[] p = new object[]{ssi,rsi}; Type[] t = new Type[] { typeof(SSI).MakeByRefType(), typeof(RSI) }; actual = (bool) privateTarget.Invoke("GotSSI",t,p); 

The GotSSI method works. I tested it in debug mode in Unit test, and I see that the 'ssi' out variable is set inside the method before returning true or false. But when the test returns its own code, the 'ssi' variable is still zero. Thus, the problem is that the object that I created in the "GotSSI" method does not understand the method of calling PrivateObject.

Does anyone know what I'm missing?

Update (solution from Rafal)

Rafal's solution works great, and here's how I implemented the solution.

I created a delegate:

 delegate bool GotSSIInternal(out SSI ssi, RSI rsi); 

And when I created the object that I wanted to test, I create a delegate (the goal is the object I am testing):

 GotSSIInternal gotSSIInternal = (GotSSIInternal) Delegate.CreateDelegate( typeof (GotSSIInternal), target, typeof(OfflineResolver).GetMethod("GotSSI", BindingFlags.NonPublic | BindingFlags.Instance)); 

After that, it is very simple to call the delegate:

 actual = gotSSIInternal.Invoke(out ssi, rsi); 

The solution is very simple and works like a charm.

+6
source share
3 answers

your method call with out parameter is wrong if you want to get out value. See this on how to call it with reflection.

+3
source

Although the final decision that has been made works, there is a much simpler way to do this. If you follow the link provided in the accepted answer from Rafal, you will find a similar question with this, with two answers. The second answer (with the most “useful” points) is the simpler of the two.

Here is a modified version of this answer specifically for the test script:

 //method to test is a private method of the class ClassTotest with signature // TryGetCustomerData(List<Invoice> invoices, out CustomerData customerData) //set up var objToTest = new ClassToTest(); var invoices = GetInvoices(); CustomerData customerData = null; //set up the arguments var args = new object[] { invoices, customerData }; //get the MethodInfo of the method you want to test var method = typeof(ClassToTest).GetMethod("TryGetCustomerData", BindingFlags.NonPublic | BindingFlags.Instance); //invoke it var success = (bool)method.Invoke(objToTest, args); //get back the customerData argument - the "out" parameter var actual = args[1] as CustomerData; 
+4
source

You need to ask yourself if you really need to check private methods? I personally do not test private methods, but it all depends on personal opinion (and it can get very hot). There are many reasons / articles / opinions. A good stream of SO can be found here .

Excerpt from the accepted answer: "A private method is an implementation detail that should be hidden for class users. Testing private methods interrupts encapsulation ..."

The reason I don't test my private methods is because they are more likely to change than the open interface. If you cover all your private methods, this will make refactoring more difficult (again, just my opinion). If you change the private method and breaks in the open interface, you will find out that your unit tests will fail, and then you can deploy.

This is just my opinion, and I know that many disagree, so just put it there!

0
source

All Articles