Mocked method not invoked - mockito

public class Employee {
public void getAddress(){
Address add = new Address();
String a = add.addAddress();
System.out.println(a);
}
}
public class Address {
public String addAddress(){
return "Emp Address";
}
}
public class MockitoTest {
#Mock
Address add;
#Before
public void setup(){
MockitoAnnotations.initMocks(this);
}
#Test
public void testEmployee(){
when(add.addAddress()).thenReturn("mocked address");
Employee e = new Employee();
e.getAddress();
}
}
In the above example, I want to mock addAddress() method in address class.When I run mockito,it is calling the real method addAddress() than the mocked one and printing "Emp Address",instead of "mocked address".I need "mocked address" as output.

Problem is as mentioned by #pvpkiran in the question comment. If you want to have mocked behavior, you need to provide provision to pass the mocked Address object to Employee.
One way to do that is
public class Employee {
public void getAddress(Address add) {
String a = add.addAddress();
System.out.println(a);
}
}
public class MockitoTest {
#Mock
Address add;
#Before
public void setup(){
MockitoAnnotations.initMocks(this);
}
#Test
public void testEmployee(){
when(add.addAddress()).thenReturn("mocked address");
Employee e = new Employee();
e.getAddress(add);
}
}
Edited: With Powermock (tested with org.powermock:powermock-mockito-release-full:1.6.4)
import static org.mockito.Mockito.when;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
class Employee {
public void getAddress() {
Address add = new Address();
String a = add.addAddress();
System.out.println(a);
}
}
class Address {
public String addAddress() {
return "Emp Address";
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest(Employee.class)
public class MockitoTest {
#Mock
Address add;
#Test
public void testEmployee() throws Exception {
when(add.addAddress()).thenReturn("mocked address");
PowerMockito.whenNew(Address.class).withNoArguments().thenReturn(add);
Employee e = new Employee();
e.getAddress();
}
}

Related

Is Lombok's builder thread safe?

I have a simple object
#Data
#Builder
public class Address {
private Long id;
private String street;
}
I make delombok of #Builder annotation and I see next code generated
#Data
public class Address {
private Long id;
private String street;
#java.beans.ConstructorProperties({"id", "street"})
Address(Long id, String street) {
this.id = id;
this.street = street;
}
public static AddressBuilder builder() {
return new AddressBuilder();
}
public static class AddressBuilder {
private Long id;
private String street;
AddressBuilder() {
}
public AddressBuilder id(Long id) {
this.id = id;
return this;
}
public AddressBuilder street(String street) {
this.street = street;
return this;
}
public Address build() {
return new Address(id, street);
}
public String toString() {
return "Address.AddressBuilder(id=" + this.id + ", street=" + this.street + ")";
}
}
}
Looking to this I see that builder is some static inner class of my Address class.
Let's imagine that I have 2 threads that uses builder executing in parallel.
First thread creates this local variable
Address address = Address.builder()
.id(1L)
.street("street 1")
.build();
Second one creates this local one
Address address = Address.builder()
.id(2L)
.street("street 2")
.build();
Looking to the implementation of lombok that uses static classes is it possible that running in parallel I'll have sometimes inside one of the threads an object id=1L street="street 2" or id=2L street="street 1"?
It is thread safe. In the method builder a new AddressBuilder object is created, so it is always working with a new object. The methods are only using local variables, no shared variables.
To test this, I wrote the wollowing unit test:
import com.anarsoft.vmlens.concurrent.junit.ConcurrentTestRunner;
#RunWith(ConcurrentTestRunner.class)
public class TestLombok {
#Test
public void testOne()
{
Address address = Address.builder()
.id(1L)
.street("street 1")
.build();
}
#Test
public void testTwo()
{
Address address = Address.builder()
.id(2L)
.street("street 2")
.build();
}
}
with vmlens, a tool to detect race conditions, and it did not found as expected any races.
The ConcurrentTestRunner used in the unit test is running the test method with 4 threads in parallel.

java.lang.ClassCastException: org.apache.log4j.Logger cannot be cast

I extended org.apache.log4j.Logger for implementing logging for method starts and exists.
It works fine, when I don't set the loglevel for a class in my log4j.properties.
When I set
log4j.logger.de.martinm.tools.UniCredit.ExportOperator=INFO
I get an exception:
Exception in thread "main" java.lang.ClassCastException: org.apache.log4j.Logger cannot be cast to de.martinm.tools.Logging.MMLogger
at de.martinm.tools.UniCredit.ExportOperator.(ExportOperator.java:21)
at de.martinm.tools.UniCredit.ExportOperator.main(ExportOperator.java:330)
public class MMLogger extends Logger {
private static MyLoggerFactory myFactory = new MyLoggerFactory();
public MMLogger(String name) {
super(name);
}
public static Category getInstance(String name) {
return Logger.getLogger(name, myFactory);
}
public static Logger getLogger(String name) {
return Logger.getLogger(name, myFactory);
}
public void enter(Logger logger, String method) {
super.debug(method+" enter");
}
public void exit(Logger logger, String method) {
super.debug(method+" exit");
}
public void debug(Logger logger, String method, String text) {
super.debug(method+" "+text);
}
public void warn(Logger logger, String method, String text) {
super.warn(method+" "+text);
}
public void info(Logger logger, String method, String text) {
super.info(method+" "+text);
}
public void error(Logger logger, String method, String text) {
super.error(method+" "+text);
}
}
public class MyLoggerFactory implements LoggerFactory {
/**
The constructor should be public as it will be called by
configurators in different packages. */
public
MyLoggerFactory() {
}
public
Logger makeNewLoggerInstance(String name) {
return new MMLogger(name);
}
}
Here is part of my code
public class ExportOperator {
//public static Logger logger = Logger.getLogger(ExportOperator.class.getName());
public MMLogger Mylogger = (MMLogger) MMLogger.getLogger(ExportOperator.class.getName());
public Connection db_con;
static Utils my_utils = new Utils();
public Properties props = new Properties();
public String output_dir;
public int mid;
public String admin_id;
public int op_id;

Mocking a method inside my test class

Android Studio 2.3
I have the following method I want to test inside my model class:
public class RecipeListModelImp implements RecipeListModelContract {
private Subscription subscription;
private RecipesAPI recipesAPI;
private RecipeSchedulers recipeSchedulers;
#Inject
public RecipeListModelImp(#NonNull RecipesAPI recipesAPI, #NonNull RecipeSchedulers recipeSchedulers) {
this.recipesAPI = Preconditions.checkNotNull(recipesAPI);
this.recipeSchedulers = Preconditions.checkNotNull(recipeSchedulers);
}
#Override
public void getRecipesFromAPI(final RecipeGetAllListener recipeGetAllListener) {
subscription = recipesAPI.getAllRecipes()
.subscribeOn(recipeSchedulers.getBackgroundScheduler())
.observeOn(recipeSchedulers.getUIScheduler())
.subscribe(new Subscriber<List<Recipe>>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
recipeGetAllListener.onRecipeGetAllFailure(e.getMessage());
}
#Override
public void onNext(List<Recipe> recipe) {
recipeGetAllListener.onRecipeGetAllSuccess(recipe);
}
});
}
#Override
public void shutdown() {
if(subscription != null && !subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
}
}
Inside my test class I am testing like this:
public class RecipeListModelImpTest {
#Mock Subscription subscription;
#Mock RecipesAPI recipesAPI;
#Mock RecipeListModelContract.RecipeGetAllListener recipeGetAllListener;
#Mock List<Recipe> recipes;
#Inject RecipeSchedulers recipeSchedulers;
private RecipeListModelContract recipeListModel;
#Before
public void setup() {
TestBusbyComponent testBusbyComponent = DaggerTestBusbyComponent.builder()
.mockRecipeSchedulersModule(new MockRecipeSchedulersModule())
.build();
testBusbyComponent.inject(RecipeListModelImpTest.this);
MockitoAnnotations.initMocks(RecipeListModelImpTest.this);
recipeListModel = new RecipeListModelImp(recipesAPI, recipeSchedulers);
}
#Test(expected = NullPointerException.class)
public void testShouldThrowExceptionOnNullParameter() {
recipeListModel = new RecipeListModelImp(null, null);
}
#Test
public void testRecipeListModelShouldNotBeNull() {
assertNotNull(recipeListModel);
}
#Test
public void testShouldGetRecipesFromAPI() {
when(recipesAPI.getAllRecipes()).thenReturn(Observable.just(recipes));
recipeListModel.getRecipesFromAPI(recipeGetAllListener);
verify(recipesAPI, times(1)).getAllRecipes();
verify(recipeGetAllListener, times(1)).onRecipeGetAllSuccess(recipes);
verify(recipeGetAllListener, never()).onRecipeGetAllFailure(anyString());
}
#Test
public void testShouldFailToGetRecipesFromAPI() {
when(recipesAPI.getAllRecipes())
.thenReturn(Observable.<List<Recipe>>error(
new Throwable(new RuntimeException("Failed to get recipes"))));
recipeListModel.getRecipesFromAPI(recipeGetAllListener);
verify(recipesAPI, times(1)).getAllRecipes();
verify(recipeGetAllListener, times(1)).onRecipeGetAllFailure(anyString());
verify(recipeGetAllListener, never()).onRecipeGetAllSuccess(recipes);
}
#Test
public void testShouldShutdown() {
when(subscription.isUnsubscribed()).thenReturn(false);
final Field subscriptionField;
try {
subscriptionField = recipeListModel.getClass().getDeclaredField("subscription");
subscriptionField.setAccessible(true);
subscriptionField.set(recipeListModel, subscription);
} catch(NoSuchFieldException e) {
e.printStackTrace();
}
catch(IllegalAccessException e) {
e.printStackTrace();
}
recipeListModel.shutdown();
verify(subscription, times(1)).unsubscribe();
}
}
However, the problem is the Subscription in my model class is always null so will never enter the if blook. Is there any way to test this with using Mockito or spys?
Many thanks for any suggestions,
You should for testing recipeListModel class, where you have shutdown() method , set mock into this class.
If you don't have set method for subscription in recipeListModel , or constructor param.... ),you can set mock object with reflection like :
#Test
public void testShouldShutdown() {
Subscription subscription = mock(Subscription.class);
when(subscription.isUnsubscribed()).thenReturn(false);
Field subscriptionField = recipeListModel.getClass().getDeclaredField("subscription");
subscriptionField.setAccessible(true);
subscriptionField.set(recipeListModel, subscriptionMock);
recipeListModel.shutdown();
verify(subscription, times(1)).unsubscribe();
}
after your update :
if you can't change way of creation , you should mock it like (full way of creation) , i don't know your api , so it's just idea:
Subscription subscription = mock(Subscription.class);
when(subscription.isUnsubscribed()).thenReturn(false);
// preparation mock for create Subscription
//for recipesAPI.getAllRecipes()
Object mockFor_getAllRecipes = mock(....);
when(recipesAPI.getAllRecipes()).thenReturn(mockFor_getAllRecipes );
//for subscribeOn(recipeSchedulers.getBackgroundScheduler())
Object mockFor_subscribeOn = mock();
when(mockFor_getAllRecipes.subscribeOn(any())).thenReturn(mockFor_subscribeOn);
//for .observeOn(recipeSchedulers.getUIScheduler())
Object mockFor_observeOn = mock();
when(mockFor_subscribeOn .observeOn(any())).thenReturn(observeOn);
// for .subscribe
when(observeOn.subscribe(any()).thenReturn(subscription);

Using a string to specify an object in Java

I have a Combo Bx (Dropdown box) with an index range of 0-20. If there anyways I can use that index to specify which object I want data from? All of the objects use the same naming convention obj0, obj1, obj2, etc. Basically something like this...
public abstract class Person {
private String name;
private String title;
private String email;
private String job;
public Person(String name, String title, String email, String job){
this.name = name;
this.title = title;
this.email = email;
this.job = job;
}
//Getters and Setters
}
public class main extends javax.swing.JFrame {
...misc code...
private void btn_startActionPerformed(java.awt.event.ActionEvent evt) {
Person obj0 = new Person("Jon Doe",
"Program Coordinator",
"jon.doe#test.com",
"Faculty");
Person obj1 = ...
...
Person obj20 = ...
/*
Onclick it uses the index of the current index in the combobox (dropdown)
to specify which object to get the data from.
*/
private void btn_GetActionPerformed(java.awt.event.ActionEvent evt) {
//Uses the obj naming convention plus the index
string foo = "obj" + toString(combobox_Name.getSelectedIndex());
//Fills the textbox using the above string and the getName method
txtbox_username.setText(ToObject(foo).getName);
}
I have created a basic design of what I think you want:
This code creates 20 objects, adds them to a combobox and uses their predefined name when selected to change a textfield.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
class ObjExample {
String name;
public ObjExample(String name) {
this.name = name;
}
#Override
public String toString() {
return name;
}
}
public class Main extends JFrame implements ActionListener {
JComboBox jcb = new JComboBox();
JTextField jtf = new JTextField("Text Field");
public Main() {
setSize(200, 200);
setDefaultCloseOperation(EXIT_ON_CLOSE);
for (int i = 0; i <= 20; i++) {
jcb.addItem(new ObjExample(Integer.toString(i)));
}
jcb.addActionListener(this);
add(jcb);
add(jtf);
setVisible(true);
}
public static void main(String[] args) {
new Main();
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == jcb) {
ObjExample obj = (ObjExample) jcb.getSelectedItem();
jtf.setText(obj.toString());
}
}
}

JAXB issue-- unexpected element

My JAXB parser suddenly stopped working today. It was working for several weeks. I get the following message. I haven't changed this code for several weeks. Wondering if this set up is good.
EDIT 2: Please could somebody help me! I can't figure this out.
EDIT 1:
My acceptance tests running the same code below are working fine. I believe this is a
classloading issue. I am using the JAXB and StAX in the JDK. However, when I deploy to jboss 5.1, I get the error below. Using 1.6.0_26 (locally) and 1.6.0_30 (dev server). Still puzzling over a solution.
unexpected element (uri:"", local:"lineEquipmentRecord"). Expected
elements are
<{}switchType>,<{}leSwitchId>,<{}nodeAddress>,<{}leId>,<{}telephoneSuffix>,<{}leFormatCode>,<{}groupIdentifier>,<{}telephoneNpa>,<{}telephoneLine>,<{}telephoneNxx>
Here is my unmarshalling class:
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
public class PartialUnmarshaller<T> {
XMLStreamReader reader;
Class<T> clazz;
Unmarshaller unmarshaller;
public PartialUnmarshaller(InputStream stream, Class<T> clazz) throws XMLStreamException, FactoryConfigurationError, JAXBException {
this.clazz = clazz;
this.unmarshaller = JAXBContext.newInstance(clazz).createUnmarshaller();
unmarshaller.setEventHandler(new ValidationEventHandler() {
#Override
public boolean handleEvent(ValidationEvent event) {
System.out.println(event.getMessage());
return true;
}
});
this.reader = XMLInputFactory.newInstance().createXMLStreamReader(stream);
/* ignore headers */
skipElements(XMLStreamConstants.START_DOCUMENT);
/* ignore root element */
reader.nextTag();
/* if there's no tag, ignore root element's end */
skipElements(XMLStreamConstants.END_ELEMENT);
}
public T next() throws XMLStreamException, JAXBException {
if (!hasNext())
throw new NoSuchElementException();
T value = unmarshaller.unmarshal(reader, clazz).getValue();
skipElements(XMLStreamConstants.CHARACTERS, XMLStreamConstants.END_ELEMENT);
return value;
}
public boolean hasNext() throws XMLStreamException {
return reader.hasNext();
}
public void close() throws XMLStreamException {
reader.close();
}
private void skipElements(Integer... elements) throws XMLStreamException {
int eventType = reader.getEventType();
List<Integer> types = new ArrayList<Integer>(Arrays.asList(elements));
while (types.contains(eventType))
eventType = reader.next();
}
}
This class is used as follows:
List<MyClass> lenList = new ArrayList<MyClass>();
PartialUnmarshaller<MyClass> pu = new PartialUnmarshaller<MyClass>(
is, MyClass.class);
while (pu.hasNext()) {
lenList.add(pu.next());
}
The XML being unmarshalled:
<?xml version="1.0" encoding="UTF-8"?>
<lineEquipment>
<lineEquipmentRecord>
<telephoneNpa>333</telephoneNpa>
<telephoneNxx>333</telephoneNxx>
<telephoneLine>4444</telephoneLine>
<telephoneSuffix>1</telephoneSuffix>
<nodeAddress>xxxx</nodeAddress>
<groupIdentifier>LEN</groupIdentifier>
</lineEquipmentRecord>
<lineEquipmentRecord>
<telephoneNpa>111</telephoneNpa>
<telephoneNxx>111</telephoneNxx>
<telephoneLine>2222</telephoneLine>
<telephoneSuffix>0</telephoneSuffix>
<nodeAddress>xxxx</nodeAddress>
<groupIdentifier>LEN</groupIdentifier>
</lineEquipmentRecord>
</lineEquipment>
Finally, here is MyClass:
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* This class is used as an envelope to hold Martens
* line equipment information.
* #author spgezf
*
*/
#XmlRootElement(name="lineEquipmentRecord")
public class MyClass {
private String telephoneNpa;
private String telephoneNxx;
private String telephoneLine;
private String telephoneSuffix;
private String nodeAddress;
private String groupIdentifier;
public MyClass(){
}
// Getters and Setters.
#XmlElement(name="telephoneNpa")
public String getTelephoneNpa() {
return telephoneNpa;
}
public void setTelephoneNpa(String telephoneNpa) {
this.telephoneNpa = telephoneNpa;
}
#XmlElement(name="telephoneNxx")
public String getTelephoneNxx() {
return telephoneNxx;
}
public void setTelephoneNxx(String telephoneNxx) {
this.telephoneNxx = telephoneNxx;
}
#XmlElement(name="telephoneLine")
public String getTelephoneLine() {
return telephoneLine;
}
public void setTelephoneLine(String telephoneLine) {
this.telephoneLine = telephoneLine;
}
#XmlElement(name="telephoneSuffix")
public String getTelephoneSuffix() {
return telephoneSuffix;
}
public void setTelephoneSuffix(String telephoneSuffix) {
this.telephoneSuffix = telephoneSuffix;
}
#XmlElement(name="nodeAddress")
public String getNodeAddress() {
return nodeAddress;
}
public void setNodeAddress(String nodeAddress) {
this.nodeAddress = nodeAddress;
}
#XmlElement(name="groupIdentifier")
public String getGroupIdentifier() {
return groupIdentifier;
}
public void setGroupIdentifier(String groupIdentifier) {
this.groupIdentifier = groupIdentifier;
}
}
Thanks, this is classloading issue I couldn't overcome so I abandoned JAXB.
Your PartialUnmarshaller code worked for me. Below is an alternate version that changes the skipElements method that may work better.
import java.io.InputStream;
import java.util.NoSuchElementException;
import javax.xml.bind.*;
import javax.xml.stream.*;
public class PartialUnmarshaller<T> {
XMLStreamReader reader;
Class<T> clazz;
Unmarshaller unmarshaller;
public PartialUnmarshaller(InputStream stream, Class<T> clazz) throws XMLStreamException, FactoryConfigurationError, JAXBException {
this.clazz = clazz;
this.unmarshaller = JAXBContext.newInstance(clazz).createUnmarshaller();
unmarshaller.setEventHandler(new ValidationEventHandler() {
#Override
public boolean handleEvent(ValidationEvent event) {
System.out.println(event.getMessage());
return true;
}
});
this.reader = XMLInputFactory.newInstance().createXMLStreamReader(stream);
/* ignore headers */
skipElements();
/* ignore root element */
reader.nextTag();
/* if there's no tag, ignore root element's end */
skipElements();
}
public T next() throws XMLStreamException, JAXBException {
if (!hasNext())
throw new NoSuchElementException();
T value = unmarshaller.unmarshal(reader, clazz).getValue();
skipElements();
return value;
}
public boolean hasNext() throws XMLStreamException {
return reader.hasNext();
}
public void close() throws XMLStreamException {
reader.close();
}
private void skipElements() throws XMLStreamException {
while(reader.hasNext() && !reader.isStartElement()) {
reader.next();
}
}
}

Resources