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

Java - Download image from URL
All the values are fetched instead of selected value in selenium
unable to parse regular expression
HttpURLConnection Post Android
Local cluster word count storm topology not working
How could one efficiently find the missing timestamps from a given time series compared to all other available time series?
UpdateTableSpec on dynamoDB table is not working
Full image adapter error
OpenSessionInView Pattern
build.gradle access public variable from another class — manifest placeholders
How to get static resource (js, css) as ClassPathResource in Spring Boot?
take real time twitter data with a keyword and save it to txt file in java
Running TestNG via Command Line
Using an interger Arraylist to extract words from a string
Spring 4.3.5 annotation based configuration tomcat-8 404 in eclipse neon 2
How to implement in jna a structure sizeof() with an union type

Categories

HOME
cakephp
variables
gitlab
asp.net-core
gerrit
omnet++
push-notification
stock
fft
youtube-dl
cakephp-2.5
gps
icloud
baqend
alpha
pivotal-cloud-foundry
upload
virtualization
quicklook
quickfix
jsprit
iolanguage
footer
visual-composer
scriptcs
web-sql
claims-based-identity
android-widget
opennlp
cas
intel-pin
internet-explorer-9
assistant
bluestacks
junit5
google-cloud-endpoints-v2
twilio-api
functor
code-contracts
webtest
hybridauth
rotational-matrices
io-redirection
suricata
web-mining
webix-treetable
reportbuilder
g-code
estimote
midl
slick-3.0
rainbowtable
termination
pnotify
celery-task
capacity
python-cryptography
titanium-android
dynamics-sl
sonarlint-vs
gnome-shell-extensions
nested-sets
httplistener
elements
mongocsharpdriver
hsv
lib.web.mvc
muse
vstest.console.exe
iiviewdeckcontroller
truevault
apache-commons-net
tween
network-interface
applescript-objc
onactivityresult
p4java
jboss-weld
monomac
ivyde
inbox
ocunit
unc
libstdc++
trusted
postgresql-performance
nsdatecomponents
data-loss
table-footer
ecl
actionview
datareader
radcombobox
blitz++
infrastructure
microsoft-virtualization
data-driven
procedural-music
spec#
.net-1.0
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