1

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,644
  • 7
  • 25
  • 48
  • 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

10

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,787
  • 12
  • 16
  • 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
  • 7,601
  • 1
  • 30
  • 33