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

how to calculate total of column in JTable but started at particular index
Spring boot with Google Cloud SQL
Android alerts: how to upgrade AlertDialog from old style (black) to new style (white)?
RealmMigration erased every data in my realm
Quartz JdbcStore + Spring
Using x509 Certs with Apache Curator
Slowly trying to code something in java that will say if insertion of brackets is correct (arithmetic)
Java regex, find a specific key : value with digits, with or without comma separated
Implementing three functions at once into a Different Evolution Optimizer
Resources required for running application on server VS running application in LXC container?
IBM MQ Java Error :: java.lang.ClassNotFoundException: com.ibm.mq.internal.MQCommonServices
Regex Expression to find content between tags [closed]
Stack algorithm is not working pefectly in Java
remove item from combobox when select using java
Java regex, unable to capture last group properly
Control before setting a boolean?

Categories

HOME
twitter
pdf
clips
gitlab
vbscript
routes
google-docs
jxls
umd
ios-charts
android-youtube-api
medical
dacpac
izpack
etl
resize
foselasticabundle
fatal-error
excel-vba-mac
conemu
web-sql
captiveportal
smb
xpages-ssjs
virtualdub
libssl
objectanimator
flink-streaming
bosh
contact-form
textmate
xmlreader
mapbox-gl
neuroscience
squib
sas-visual-analytics
fedex
dynamic-reports
http-live-streaming
import-from-excel
xml-documentation
osx-mavericks
chain-builder
atomicity
errordocument
tactic
sqlbulkcopy
fuzzy-search
bgp
fadeout
hexdump
ios4
browser-link
wso2cloud
lib.web.mvc
arcanist
mono-embedding
unity3d-gui
apache-commons-net
geonetwork
codeigniter-routing
applescript-objc
valueconverter
reactfx
braille
algebraic-data-types
pyhdf
geos
commoncrypto
google-cloud-save
flash-builder4.5
django-nonrel
yui-compressor
jquery-knob
rdoc
joyent
f#-powerpack
datareader
html-input
h.323
dmx512
firefox-5
user-friendly
multi-tier
swing-app-framework
eqatec
xetex
pascal-fc
misv

Resources

Encrypt Message



code
soft
python
ios
c
html
jquery
cloud
mobile