• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

How to unit test a value object that depends on services?

 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If I have the following value object class PhoneNumber:



If I wanted to test my PhoneNumber class correctly I would need to Stub both Pattern and Matcher classes so that the code is tested in isolation. However, since I'm not injecting them into my class I have no way to alter the implementation of the classes. I'm tied to these types.

Maybe I should have injected them through my constructor, but that way I would be injecting an injectable into a newable according to Misko Hevery To "new" or not to "new"....

How do you test such class in isolation?

note that this is only an overly simplified example. There could be many rules for validating my value object and some serious logic that need proper testing.
 
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to JavaRanch.

I would need to Stub both Pattern and Matcher classes so that the code is tested in isolation.


Why? Those classes are part of the JRE, you're not testing them (and I certainly wouldn't call them "services"). I see nothing wrong with instantiating them - you can't possibly avoid instantiating any classes that are part of the JRE.
 
songo han
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Why? Those classes are part of the JRE, you're not testing them (and I certainly wouldn't call them "services"). I see nothing wrong with instantiating them - you can't possibly avoid instantiating any classes that are part of the JRE.



Well to tell you the truth I'm still learning my way into proper unit testing. In numerous books I read about how unit testing should be done in isolation. Meaning that every test should test only one unit in isolation from its collaborators.

That's why people use Stubs/Mocks to fake collaborators and test the class in isolation. How can I be sure that my test isn't failing because there is a bug in the Parser or Matcher classes?
 
Ulf Dittmer
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Those classes don't change. If there's is a bug in them, you'd find it during your normal development and testing activities (unless it's an obscure one, but then the unit test wouldn't find it either).
The OpenJDK project is sure to have plenty of unit tests for those classes that are way more elaborate than anything you would ever come up with.

That article talks about classes you write, or classes that might differ between development and production (maybe using a test service vs. a real service), or classes that might not be present in a development or test environment (like an HttpServletRequest if you're writing servlets). It does not apply to these objects that are the same everywhere.
 
songo han
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I see your point. So if I use a JRE class then it's safe to just use it directly in my test cases.

But what if I used a custom validator class that I built like this:

Since PhoneValidator is a custom class that I built it may have some errors. What should I do then?

This is just a simplification as in real life I may need more complex objects than a validator.
 
Ulf Dittmer
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I still see nothing wrong with instantiating that class. You may want to use a factory instead, if there can be different PhoneValidator implementations (in which case PhoneValidator would likely be an interface, or a superclass), and you want to unit test all of them.

Note how that article talks specifically about a situation where the object that would be used in production (the MusicPlayer) can't be instantiated in the test environment, because the hardware is not available. So that would be similar to the HttpServletRequest situation I mentioned.
 
songo han
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
aah I see. Now it makes since. Thanks for the help
reply
    Bookmark Topic Watch Topic
  • New Topic