0

I am using C# MOQ library.

Lets say I want to create a UnitTest for this piece of code:

if(condition){
    privateMethod();
}
else{
    logger.info("didn't hit")
}

I want to check if privateMethod was hit, I can't use the Verify function as it is private. How can I do that?

I thought about adding a Status member dedicated for the unit testing, which will hold the last location before exiting the tested method.

omriman12
  • 1,528
  • 6
  • 24
  • 45
  • Could the access of this `privateMethod` be eventually changed to `protected`? – Daniel Dušek Jun 05 '17 at 08:01
  • https://stackoverflow.com/questions/6847463/using-moq-to-verify-execution-of-private-methods – pizycki Jun 05 '17 at 08:01
  • 2
    If you want to test a call of method you have to extract your private method to a new class and mock it. Otherwise you should focus on the effects of your private method. Example: if your methods writes some data to a file you can check for the file to be created – Grappachu Jun 05 '17 at 08:03
  • @Grappachu But if the methods writes some data to a file we have left unit test and doing integration test and the class itself is not valid for unit test – Sir Rufo Jun 05 '17 at 08:10
  • @SirRufo you're right, i didn't choose a top example. – Grappachu Jun 05 '17 at 08:13

2 Answers2

9

Don't test private methods. They are private implementation details of the class. You should only test the results of executing public methods.

Properly designed SOLID code will never put you in a position which will require you to do private mocking.

Depending on whether you want to change your design or not, there are few approaches you could take:

  • don't try to mock private details, focus on public API (doesn't help with design issue)
  • extract private method to class, introduce dependency (long-term solution, improves design and makes code easily testable)
  • make private method protected, override in test (doesn't help with design issue, might not yield valuable test)

Whichever you chose I leave up to you. However, I'll emphasize it one more time - mocking private method is not unit testing, library or tools problem - it is a design problem and is best solvable as such.

Ivan Mladenov
  • 1,635
  • 9
  • 15
  • Although the things you have written about unit testing the private method are correct, it doesn't answers OP's question. As OP want to know a way to find out if the call to his private method is made or not, from the public method he is testing. – Yogi Jun 05 '17 at 08:09
  • This class is a `Manager`, and this method is his start point. So it has some private logic which cannot be `Mocked`. So what i want to test here is for example: make sure the manager initiates the right amount of workers, etc. Maybe its not current to unit test such method? – omriman12 Jun 05 '17 at 08:12
  • I have given you 3 alternatives to what you can do. My suggestion is to inject another unit as a dependency that does all those things, or maybe even make the method protected and override it. – Ivan Mladenov Jun 05 '17 at 08:13
1

I use MSTest and this is the solution I use in the Test Class to invoke Private Method:

Class target = new Class();
PrivateObject obj = new PrivateObject(target);
var retVal = obj.Invoke("PrivateMethod");
Assert.AreEqual(retVal);

It use the PrivateObject Class

Habeeb
  • 6,865
  • 1
  • 27
  • 31