This week's book giveaway is in the Performance forum.
We're giving away four copies of The Java Performance Companion and have Charlie Hunt, Monica Beckwith, Poonam Parhar, & Bengt Rutisson on-line!
See this thread for details.
Win a copy of The Java Performance Companion this week in the Performance forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Mock static method

 
Niall Loughnane
Ranch Hand
Posts: 209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I have the following class



and want to test different values returned from this class,

I have used PowerMock but find this not doing my item because it is throwing "java.lang.OutOfMemoryError: PermGen space" exception,

Are there alternatives to using PowerMock or what do you think?

Thanks,

Niall
 
Junilu Lacar
Bartender
Posts: 7481
50
Android Eclipse IDE IntelliJ IDE Java Linux Mac Scala Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't understand what you could possibly test here. It's a static method returning a hard-coded value. What's there to test?
 
Niall Loughnane
Ranch Hand
Posts: 209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
its just an example :) like i wasnt going to print production system code :)
 
Bill Gorder
Bartender
Posts: 1682
7
Android IntelliJ IDE Linux Mac OS X Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
PowerMock will work. You don't need to post production code but you do need to at least post a relevant example of what you are trying to mock. If you don't take the time to post a good question people will not take the time to post a good answer. If you are getting an out of memory error you are most likely doing something wrong. Give an example of what you tried that is giving the OOM and we can maybe help you figure out what you are doing wrong.
 
Junilu Lacar
Bartender
Posts: 7481
50
Android Eclipse IDE IntelliJ IDE Java Linux Mac Scala Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Aside from the relevant example that Bill asked for, you're not trying to mock the class that you're testing, are you? Collaborators are what you would mock, not the class under test.
 
Niall Loughnane
Ranch Hand
Posts: 209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Thanks for the replies,

A relevant example is:


This returns an instance of the JAXBContext class that we need to test,

Thanks,

Niall

[EDIT junilu, enabled BB code tags]
 
Junilu Lacar
Bartender
Posts: 7481
50
Android Eclipse IDE IntelliJ IDE Java Linux Mac Scala Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Niall Loughnane wrote:
This returns an instance of the JAXBContext class that we need to test,

So why do you want to mock the static method? If the returned JAXBContext is what you really want to test, why don't you just set it up the way you want it to in your test instead of calling newInstance()? Your test setup will then become "sample code" for the implementation of the static method. The added benefit of doing this would be that if someone changed the implementation of the static factory methods without changing the corresponding test setup code, you'd know because a test would probably start failing.
 
Niall Loughnane
Ranch Hand
Posts: 209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Thanks for the reply but can you please clarify,

Thanks,

Niall
 
Junilu Lacar
Bartender
Posts: 7481
50
Android Eclipse IDE IntelliJ IDE Java Linux Mac Scala Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Answer the questions first; ignore the rest of my reply for now.
 
Bill Gorder
Bartender
Posts: 1682
7
Android IntelliJ IDE Linux Mac OS X Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
another question is why are you testing the Framework?

http://docs.oracle.com/javase/6/docs/api/javax/xml/bind/JAXBContext.html#newInstance%28java.lang.Class[],%20java.util.Map%29

Test your code and trust that the people who wrote the Java libraries tested theirs.
 
Junilu Lacar
Bartender
Posts: 7481
50
Android Eclipse IDE IntelliJ IDE Java Linux Mac Scala Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Good question, Bill. I suspect that Niall just gave us an example that's similar to his situation.

@Niall, if you're not going to post actual code, it's going to be difficult to have a coherent discussion because of the likelihood of losing something in translation between the example and the actual and vice versa.
 
Niall Loughnane
Ranch Hand
Posts: 209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Thanks,

The code that I'm trying to mock is:
* in a Java application
* there is a class that is an interface for reading configuration properties
* the configuration properties are set when a JVM command line is ran (i.e. the JVM command line is: "java -jar bookstore.jar -Dnames=john,peter,paul -Dtimes=4")
* The class that is used for reading configuration properties is called "Config"
* There is a data transfer object for storing the names and index times "NameDTO"
* There is a service class that processes the configuration properties into dto objects

The code for the configuration class is:


The code for the service class is:


The code for the Data Transfer Object is:


This:
* retrieves 2 configuration values for the system "NAMES (String)" and "TIMES (Integer)"
* There are default values set: NAMES:<blank> and TIMES:1
* Creates a dto instance "NameDTO" for separate names and times

The unit tests are:

The unit tests for the dto class is:


The code for the service class is:


But instead of setting global properties on the System (via System.setProperty), I would like to mock "Config" and set the values returned from this class per test,

Thanks in Advance,

Niall

[Edit: enabled BB Code Tags]
 
Junilu Lacar
Bartender
Posts: 7481
50
Android Eclipse IDE IntelliJ IDE Java Linux Mac Scala Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Niall, prior to posting replies that include code listings, please make sure the "Disable BB Code in this message" option is not selected. You can also use the "Preview" to see what your post is going to look like when you submit it.

I would do some refactoring of service class first. The hard reference to the Config class makes it more difficult to test, so you need to soften up that reference first. Consider a constructor that takes an instance of Config. Then you can provide a "test" implementation of Config and pass that in when you do your test setup.

 
Niall Loughnane
Ranch Hand
Posts: 209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Junilu,

Thanks will do,

If an instance of Config is going to be passed as a constructor variable then the methods within Config will need to be changed from static methods to instance methods but this isn't possible because in some instances Config is a third party class that contains static methods?

Thanks in Advance,

Niall
 
Junilu Lacar
Bartender
Posts: 7481
50
Android Eclipse IDE IntelliJ IDE Java Linux Mac Scala Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Then my work-around would be to create a Bridge class that I can control. That is, create your own class, one that you can instantiate. The production implementation would reference the third-party Config class and the test implementation would do whatever it is you need for testing purposes. I wouldn't call it "Bridge" though -- that's the design pattern name.
 
Niall Loughnane
Ranch Hand
Posts: 209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Gotcha :)

Cool, Thanks for the info, will check it out,

Cheers
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic