10

I have a class with one public method Send() and a few private methods. It calls a couple of webservices and processes the reponse. The processing is done in private methods.

I want to unit test the code. My understanding is that unit tests should test my code in isolation (ie mock up supplier responses).

I also believe that private methods should not need to be unit tested But if I just test the Send() method my code isnt being tested in isolation and is dependent on the supplier resonse.

Should I then make my private methods public so I can test them with mock responses? It seems bad practice since I only the class should need to call them.

Apologies if its a basic question, im fairly new to unit testing.

Im using c# and VS2010

4
  • If you don't test a private method, how do you know if it works? Commented Sep 23, 2011 at 12:41
  • 1
    @BryanOakley you don't need to know that a private method works, it's private. You know that it works because the public methods that call it pass their tests.
    – StuperUser
    Commented Sep 23, 2011 at 13:24
  • @Bryan Oakley have a look at the link Commented Sep 23, 2011 at 13:49
  • Hi Tom, I've updated the link to make it more prominent and have the link text reflect its target. Please feel free to rollback.
    – StuperUser
    Commented Sep 23, 2011 at 14:06

3 Answers 3

18

You should separate the code dealing with the web services (i.e. sending and receiving data) from the code processing the results. Move the latter code into a distinct class, making the necessary methods public. Then you can easily unit test the processing logic, in isolation from the external dependencies.

By this, you also make your code conform to the Single Responsibility Principle. As a general rule of thumb, feeling the need to test private methods is often an indication that the class has too many responsibilities, thus should be refactored into multiple classes.

0
3

I think a test with such dependencies (calling suppliers webservices) is an integration test rather than a unit test.

3

As others have stated, if your unit tests have external dependencies like web services or database calls then they are NOT unit tests at all, they are integration tests.

True unit tests can run independently of outside components aside from the component they are intended to test and should be repeatable regardless of environment. If the outside web services go down, your unit test should not fail.

We get around this by using a Mocking Framework. Mock objects allow us to create a mock of a component so that the component in our unit test uses these mock objects instead of real ones. We can inject mock objects into the testable component, and specify what argument(s) we are expecting, what we would like it to return when it is called, even what exception we would like it to throw. I highly recommend reading more on the subject as it will improve the reliability and independence of your unit tests.

For a good post on different C# mocking frameworks see the following SO thread:

https://stackoverflow.com/questions/37359/what-c-mocking-framework-to-use

EDIT: For the overtly sensitive, I will own that I did neglect to mention DbUnit or other transactional tools that can rollback database changes at the end of the test. These are also repeatable and can be environment agnostic with generated test data thus a Mocking Framework is not needed in this case.

2
  • Can someone explain the downvote? I didn't rip on PHP, ROR, NoSQL databases, Javascript on the server, Apple products or any other fab trend yet I STILL got a drive-by downvote anyway :S
    – maple_shaft
    Commented Sep 23, 2011 at 13:06
  • I guess someone didn't like having their unit tests being called "not unit tests at all" (wasn't me) :)
    – Daniel B
    Commented Sep 23, 2011 at 13:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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