1

I am new writing good test cases, so please bear with me. Writing a test case for private methods

public Stock getStock(String stockTicker) {
            Stock company = new Stock();
            String url = getEndpointURL(stockTicker);
            htmlDocument = fetchHTMLDocument(url); // private method
            company.name = getStockName(); // private method uses htmlDocument
            company.actualPrice = getActualPrice(); // private method uses htmlDocument
            return company;
    }

Current Test case looks like

assertThat(selector.getActualPrice()).isGreaterThan(-1);
assertThat(selector.getStockName()).isNotNull();

But this doesn't allow me to make methods private..

To make the methods private, and since I want to test getStock only using public methods (like recommended in "How do you unit test private methods?"), I want to write test case for getStock method as below

Stock st = selector.getStock("AAPL");
assertThat(st.name).isNotNull();

i.e make assertions on Stock object

However, in this test, I want to avoid the backend call made by fetchHTML() and pass a custom Document to test the functioning of getStockName() and getActualPrice() method.

How do I do this without making methods public?

5
  • Do these methods use actually htmlDocument? it would be good if you could fix de example. Right now these methods look blind and totally opaque. On the other hand, does fetchHTMLDocument has any dependency you can mock/stubb?
    – Laiv
    Commented Sep 28, 2017 at 14:28
  • 5
    The commonly-accepted "best practice" nowadays is to unit test your private methods indirectly, through the class's public API. Commented Sep 28, 2017 at 16:44
  • @BobDalgleish: I took the freedom to edit the question a little bit, because it seems when one does not read it carefully, they can mistakenly believe it is a dupe, which it is not.
    – Doc Brown
    Commented Sep 28, 2017 at 19:37
  • @RobertHarvey yes the other methods use htmlDocument and it is internal member of class stock selector
    – Incpetor
    Commented Sep 29, 2017 at 4:55
  • The objective of a unit test is to verify the expected behaviour of the code via the contract, the implementation details should be immaterial, it should be possible to substitute an entirely different implementation, even a Mock. Commented Oct 19, 2017 at 10:20

1 Answer 1

5

I'm having a hard time understanding exactly what it is that you're asking but it seems like your question is more to do with removing the usage of an actual HTTP request than anything to do with private methods per se.

Instead of the fetchHTML function being a private function of that object, you should have a separate object that handles HTTP requests. You can then pass a mock version of this object into the constructor of the selector from tests, and this mock can return a fixed value instead of performing an actual HTTP request.

Not the answer you're looking for? Browse other questions tagged or ask your own question.