views:

84

answers:

3

Hi,

My software (application) exposes an API (webservices) using httplistener. Is it from a unit test point of view enough to test the API functions through web requests?

I ask this since I read that a best practice is to test only the public methods of a class. In this case I'm not testing public methods of a class but the public API functions from the whole component.

Thanks for any advice

+3  A: 

That would be more like an integration test. Unit tests would be testing the actual methods on classes directly. if you've got code in webmethods on web services, you should pull that code out into some service classes, which will make them easier to test. Webmethods should never do anything themselves, much like controllers in MVC.

You're right you should only need to test public methods, though. Any private method not used by a public one directly or indirectly, should be deleted anyway.

Neil Barnwell
Sometimes testing private methods that are used by more than one public method directly can save you the need to write some unit tests for your public methods. For example, when the class calls a protected method in a base class it **may** be enough to test that the public method calls the protected method and make sure the various scenarios for the protected method are tested elsewhere, not repeating those tests for this subclass. Generally, I would agree though. Integration tests at the webservice level. Unit tests at the method level, mocking out dependencies in the unit tests.
tvanfosson
@tvanfosson: Disagree. Testing that the API's call protected method isn't *best*, since it depends on a particular implementation. Having two nearly identical tests is better, since it presumes nothing. You can easily factor the redundancy out of the testing by using a common method for testing. Your testing shouldn't, however, depend on knowledge of the implementation.
S.Lott
+2  A: 

It depends on how much time you have. Once you're building an API, it's really important that you test your API functions very well.

But, if a test fails, can you find quickly where the bug is? The point of unit testing all your public methods (even if they're not exposed by your API) is to be able to quickly correct any bug you might create by changing.

Samuel Carrijo
+1  A: 

"I ask this since I read that a best practice is to test only the public methods of a class. In this case I'm not testing public methods of a class but the public API functions from the whole component. "

I can't see the hair you're splitting. Public API is the public API.

Public API methods of a class or Public API functions from a component is the same thing -- a Public API -- the only thing you should test.

You have two levels of public API: class level and component level. That says you have two levels of unit testing. Class-level unit tests and component level unit tests.

Some folks will quibble on the definition of "unit" for unit testing. Some will claim that "unit" is always a stand-alone class and nothing more. I can't see how this is true, but some folks will claim it.

A unit is atomic or indivisible. It's a unit when your test does not reflect the unit's structure.

S.Lott
I guess I would be a bit of a quibbler. I don't think it's good practice, if you can avoid it, to test both a method and its dependencies in a single unit test. This couples your test to both bits of code. Ideally, each unit test would only be coupled to the single method that it's testing. Having practiced unit testing for several years, my experience is that I'm more successful when my tests are more focused
tvanfosson
@s.lott: you word it better than me. It would seem to me that if I write a gazzilion unit tests for every api function at the class level, I would almost double this work when doing it from the webservice level. It would seem a bit redundant.
@reinier: the component-level API is different from the class-level elements, so it requires different testing. The presence of some redundancy in testing is irrelevant, since the component-level testing doesn't assume any specific class-level architecture or implementation.
S.Lott
@tvanfosson: I didn't suggest a *single* unit test. I suggested unit testing should be used for all public API's at all levels of "unit".
S.Lott