java


What is the best way to mock object instantiated inside method under test?


I have the following code and I look for the best way to test it:
public class ClientFactory {
private ConfigurationLoader loader;
public ClientFactory(ConfigurationLoader loader) {
this.loader = loader;
}
public IRest create(String something) {
Configuration config = loader.load(something);
if (magic()) {
return new ClientType1(config);
}
return new ClientType2(config);
}
}
public class ClientType1 implements IRest{
private Configuration config;
public ClientType1(Configuration config) {
this.config = config;
}
public Something doGetRequest(Long id) {
WebClient client = getHttpClient();
return client.get();
}
private WebClient getHttpClient() {
WebClient client = new WebClient();
client.setSchema(config.getSchema());
client.setHostname(config.getHostname());
client.setPort(config.getPort());
// and so on ....
return client;
}
}
I would like to test the interaction/behaviour between ConfigurationLoader and ClientType1.getHttpClient methods. From one side I think it is good idea, testing interaction between objects, from the other side, hmmm I test setters and getters - boring, no business logig is involved here. Which one is more true?
Mock of configuration object can be easily transferred into ClientType1 when it is instantiated, mocking the 'new WebClient()' seems to be the problem. I thought about:
public class ClientType1 implements IRest{
private Configuration config;
private WebClient client; // this will be replaced by mock
public ClientType1(Configuration config) {
this.config = config;
webClient = new WebClient();
}
.....
private Client getHttpClient() {
client.setSchema(config.getSchema());
....
return client;
}
}
and use PowerMock to replace private WebClient client by mock, but I am not sure it is java way. Any guidelines/suggestions?
As you have found, the new keyword makes unit testing difficult. I suggest avoiding it. I think your problem here is more of a design problem. Objects should not configure themselves. When you design an object, think about what its true dependencies are. IMO the true dependency of the ClientType1 is a WebClient or a pool of WebClient not a Configuration. IMO the true dependency of ClientFactory is a Configuration not a String.
I would redesign like so:
interface ClientFactory {
IRest create(Configuration config);
}
public class DefaultClientFactory implements ClientFactory {
private final ClientFactory magicClientFactory;
private final ClientFactory otherClientFactory;
public DefaultClientFactory(ClientFactory magicClientFactory, ClientFactory otherClientFactory) {
this.magicClientFactory = magicClientFactory;
this.otherClientFactory = otherClientFactory;
}
public IRest create(Configuration config) {
if (magic()) {
return magicClientFactory.create(config);
} else {
return otherClientFactory.create(config);
}
}
}
interface WebClientFactory {
WebClient create(Configuration config);
}
public class DefaultWebClientFactory implements WebClientFactory {
public WebClient create(Configuration config) {
WebClient client = new WebClient();
client.setSchema(config.getSchema());
client.setHostname(config.getHostname());
client.setPort(config.getPort());
return client;
}
}
public class ClientType1Factory implements ClientFactory {
private final WebClientFactory webClientFactory;
public ClientType1Factory(WebClientFactory webClientFactory) {
this.webClientFactory = webClientFactory;
}
public IRest create(Configuration config) {
return new ClientType1(webClientFactory.create(config));
}
}
public class ClientType1 implements IRest{
private final WebClient webClient;
public ClientType1(WebClient webClient) {
this.webClient = webClient;
}
public Something doGetRequest(Long id) {
return webClient.get();
}
}
Using this design you can successfully unit test each and every class defined without resorting to advanced features of PowerMock. You can unit test ClientType1 by passing in a mock WebClient. You can also test your factories by passing in different configurations and checking if the created object is what you expect. Further the code is less coupled, more flexible, and each class has a single responsibility.

Related Links

Avoid blank space between cells when resize
How to check a .JAR file is running on a windows system using c#?
Timeout last 10 min in Tomcat 7
cascadeType.REMOVE not working(JPA spring data)
Finding Process Time taken by a mule flow
Spring List<MultipartFile> returns one even though no files have been selected
Converting string ā€œsā€ to binary [closed]
How to fetch xml values from a http get response in java
ResourceOwnerPasswordResourceDetails - Pass clientid and secret to generate oauth2 token
Loop or Repeat? [duplicate]
Mouse Motion Listener delay and malfunction
Setting OnClickListener for array of checkboxes
Fastest way to import data into Neo4j with Lucene
Statistics inquiry
Will changing an object from a hashmap affect the wait() method in multiple threads?
Clueless what I'm doing wrong setting up Spring Boot REST app

Categories

HOME
pandas
listview
single-sign-on
office365api
bookshelf.js
google-docs
cmd
survey
ip
cross-validation
facebook-php-sdk
communication
ssl-client-authentication
nano-server
leiningen
visual-studio-cordova
dosgi
flux
code-review
contextmenu
crystal-reports-2008
numerical-methods
intel-pin
kannel
maquette
libssl
primitive
microsoft-chart-controls
phonegap
http-get
webtest
caret
avcapturesession
form-data
http-referer
amazon-kinesis-kpl
revolution-slider
io-redirection
suricata
restlet
multilingual
mixture-model
abstract-class
unspecified
document.write
splice
elasticsearch-plugin
lumberjack
preconditions
android-tabhost
avro4s
pdf-reactor
g-code
apple-news
azure-application-gateway
network-flow
upstart
togetherjs
pg-dump
font-size
pearson
python-cryptography
jspdf-autotable
dwscript
vtigercrm
ado.net-entity-data-model
pagedlist
ubuntu-10.04
testng-dataprovider
revolution-r
unity-networking
tcpserver
jms2
content-length
tarjans-algorithm
varargs
deis
twirl
ios9.1
directoryservices
nsmutabledictionary
tween
oxwall
pick
system.net.webexception
braille
hyprlinkr
concurrent-collections
tws
qt-faststart
hungarian-algorithm
ember-app-kit
anonymous-methods
simba
osql
mercurial-server
window-management
gcj
coredump
yui-datatable
floating
.nettiers
wsdl.exe
document-conversion

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App