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

Creating button through class
What is the PKCS#11 provider DLL for CAC Cards and where do I find it?
Error while getting currentElement in Webdyn Pro Java
Error while doing jcuda addition program
Find all possible consecutive subset in a unsorted array using JAVA
how to create a triple using map
How do i change the if statement to iterate backwards through the array?
Apache Spark SQL - Join result is empty
Save received data in java
Updating Items in Arraylist throws ConcurrentModificationException [duplicate]
Set TLSv1.2 on HttpClient using PostMethod
Swing project JPA without persistence.xml?
tomcat returns 404 for my webapp [duplicate]
Pasting text from clipboard using a button across different apps (Android)
Finding the x, y coordinate of text being drawn in a text Display
HTTP Status-Code 412: Precondition Failed. when uploading files using HttpURLConnection

Categories

HOME
vim
clips
vbscript
listview
hook
gerrit
isabelle
c#-4.0
mockito
google-api-php-client
raspberry-pi
office365api
electron
bpmn
octobercms
routes
gis
icloud
ios-charts
gitpitch
gorm
gnupg
alignment
leiningen
msp430
worldwind
openrefine
apache-metamodel
jqwidget
beyondcompare
visual-composer
microsoft-r
wpfdatagrid
user-interaction
objectanimator
delicious-api
semantic-versioning
ioio
gtrendsr
noraui
copying
host
automake
trim
awt
botbuilder
no-www
http-redirect
appcompat
revapi
python-c-api
veracode
pearson
iso8601
bind9
account-kit
synchronous
nested-sets
medium.com
file-writing
mathematica-frontend
xml-attribute
angstrom-linux
markojs
phpcas
freelancer.com-api
spidermonkey
cakephp-3.1
operation
angular-local-storage
key-management
notify
device-orientation
bigbluebutton
ng-animate
nstableviewcell
relocation
hippomocks
picturefill
oracle-warehouse-builder
industrial
jsctypes
easy-install
seed
interface-orientation
itmstransporter
gil
enter
semantic-diff
gnu-prolog
deobfuscation
krl
digest-authentication
dbal
firefox4
javap
eqatec
sustainable-pace
sector
django-notification
wsdl.exe

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