How to mock JmsTemplate with Mockito? - unit-testing

I try to test a class where i send a jms message but i can't mock the JmsTemplate
JmsProducer.class :
#Component
public class JmsProducer {
#Autowired
private JmsTemplate jmsTemplate;
#Value("${destination}")
private String destination;
public void send(String message){
jmsTemplate.convertAndSend(destination, message);
}
}
JmsProducerTest.Class :
#RunWith(SpringRunner.class)
public class JmsProducerTest {
private static final String DESTINATION= "example";
private static final String MESSAGE= "message";
#InjectMocks
private JmsProducer jmsProducer;
#MockBean
JmsTemplate jmsTemplate;
#Before
public void init(){
ReflectionTestUtils.setField(jmsProducer, "destinationQueue", DESTINATION);
}
#Test
public void testsend(){
jmsProducer.send(MESSAGE);
verify(jmsTemplate,times(1)).convertAndSend(DESTINATION, MESSAGE);
}
}
And when i run this test case it gives me : java.lang.IllegalArgumentException: object is not an instance of declaring class
Have you any idea for this issue ?

If you are using SpringRunner you should add to the init method MockitoAnnotations.initMocks(this);, because #InjectMocks will be work correct with MockitoJUnitRunner.
PS. ReflectionTestUtils.setField(jmsProducer, "destinationQueue", DESTINATION); - but your fields have another name - destination, not destinationQueue

I would also notice that it could not Mock JmsTemplate and ObjectMapper too with jdk 1.8.05 and when i change the JDK to 1.8.74 it works nice.
I referenced to the discussion

Related

Why is #Inject object(Optional) coming null while running unit test?

I have a class Room, where I inject Optional Person object, this is coming null while running testSuccess. My understanding is it should come non null, since I am setting this to new Person() at the start of the test. Why is it coming null?
public class Room{
#Inject
private Optional<Person> person1
//this is coming null when running test
}
My unit test
public class RoomTest {
#Inject Mocks
private Room testRoom
.....
//Other mocks
private Optional<Person> testPerson
//Not able to mock this since its optional, hence directly setting value in unit test.
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void testSuccess() {
testPerson = Optional.of(new Person());
....
}
}
As the name implies, #InjectMocks only injects #Mocks. The testPerson is not a mock. Why not just add an #Inject-ing constructor to the Room class that would accept a person? This way you could just instantiate a testRoom in your test method and your dependency injection will still work.
public class Room{
private Optional<Person> person;
#Inject
public Room(Optional<Person> person) {
this.person = person;
}
}
public class RoomTest {
#Test
public void testSuccess() {
Optional<Person> testPerson = Optional.of(new Person());
Room room = new Room(testPerson);
...
}
}
That said, if you absolutely want to use the annotations and adding the constructor is not an option for you then you can use PowerMock runner to mock the Optional. Conceptually, it can look like the code below. But usually, if you have to use PowerMock there might be something wrong with the code :)
public class Room{
#Inject
private Optional<Person> person;
}
// This is for JUnit4. Using Powermock with JUnit5 will be more involved
#RunWith(PowerMockitoRunner.class)
#PrepareForTest(Optional.class) // to mock the final class
public class RoomTest {
#InjectMocks
private Room testRoom;
#Mock
private Optional<Person> testPerson;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void testSuccess() {
...
}
}

Unit Testing Service Layer in Spring Boot

I have a service layer (Code Below:)
#Service
public class EquityFeedsService {
#Autowired
private EquityFeedsRedisRepositoryImpl equityFeedsRedisRepositoryImpl;
public void save(EquityFeeds equityFeeds) {
logger.info("Inside the save method of EquityFeedsService.");
equityFeedsRedisRepositoryImpl.save(equityFeeds);
}
// other methods
}
Now I am trying to write a Unit Test case for the above method below:
#ExtendWith(SpringExtension.class)
#AutoConfigureMockMvc
public class EquityFeedsServiceTest {
private MockMvc mockMvc;
#InjectMocks
private EquityFeedsService equityFeedsService;
#Mock
private EquityFeedsRedisRepositoryImpl equityFeedsRedisRepositoryImpl;
#BeforeEach
public void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(equityFeedsService).build();
}
#Test
public void testSaveMethod() {
EquityFeeds equityFeeds = new EquityFeeds(423,"SAPEXTXN1", "GS");
when(equityFeedsRedisRepositoryImpl.save(any(EquityFeeds.class))).thenReturn(new EquityFeeds());
}
}
This code gives me the below Exception:
in line (any(EquityFeeds.class))
Required type:
EquityFeeds (This is my model class)
Provided:
Matcher <com.investmentbank.equityfeedsprocessingupdated.model.EquityFeeds> (This is the fully qualified path name of the mode class)
no instance(s) of type variable(s) T exist so that Matcher<T> conforms to EquityFeeds
and Exception :
Cannot resolve method 'thenReturn(com.investmentbank.equityfeedsprocessingupdated.model.EquityFeeds)'
What is wrong with my Unit Test Case? How do i solve this?

“Invalid use of argument matchers” but I use matchers only

I wish to test the following getRights method:
public GetProductRp getRights(String aaId, String bbId, String ccId) {
GetProductRp rp = (GetProductRp) webServiceTemplate.marshalSendAndReceive(createRq(aaId, bbId, ccId));
return rp;
}
private GetProductRq createRq(String aaId, String bbId, String ccId) {
GetProductRq rq = new GetProductRq();
GetProductRqBody body = new GetProductRqBody();
body.setaaId(aaId);
body.setbbId(bbId);
body.setccId(ccId);
rq.setBody(body);
return rq;
}
This is my test class:
#RunWith(SpringRunner.class)
#SpringBootTest()
public class ClassTest {
#Autowired
private Class rightClass;
#MockBean
private WebServiceTemplate webServiceTemplate;
#Test
public void getRightsTest() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
GetProductRp response = Helper.createProductRp("xx", "yy");
Method mCreateRq = rightClass.class.getDeclaredMethod("createRq", String.class, String.class, String.class);
mCreateRq.setAccessible(true);
GetProductRq request = (GetProductRq) mCreateRq.invoke(rightClass, "12345678", "12345678", "1111");
Mockito.when(webServiceTemplate.marshalSendAndReceive(request)).thenReturn(response);
Mockito.when(rightClass.getRights(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(response);
Assert.assertNotNull(response);
}
I receive the error provided in the short description above altough I only use Matchers (Mockito.anyString())....
Any idea?
The issue here could be that you are putting #Autowired on private Class rightClass; and you are trying to mock the method of it. If you want to mock the method then you should put #MockBean annotation as :
#MockBean
private Class rightClass;

Shared Preferences is null in mockito

I am trying to mock a simple shared preferences using Mockito . Since, the examples on google are too complicated to make anything out of it, I decided to go ahead on my own.
The shared preferences are setup using dagger.
It crashes with NPE in the saveString method in the SharedPreferenceManager class on the putString line.
#Module
public class StudentModule {
#Provides
#Singleton
static Context getContext(Application application) {
return application.getApplicationContext();
}
#Provides
#Singleton
static SharedPreferences getSharedPreferences(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
}
There is a manager class:
public class SharedPreferenceManager {
private SharedPreferences sharedPreferences;
private Context context;
#Inject public SharedPreferenceManager(SharedPreferences sharedPreferences, Context context){
this.sharedPreferences=sharedPreferences;
this.context=context;
}
public String doSomething(){
return sharedPreferences.getString("s","");
}
public void saveString(String s){
System.out.println(sharedPreferences.getClass().getSimpleName());
SharedPreferences.Editor editor=sharedPreferences.edit();
editor.putString("s","bis").apply();
}
}
Here is the test:
#RunWith(MockitoJUnitRunner.class)
public class MockTest {
#InjectMocks
SharedPreferenceManager sharedPreferenceManager;
#Mock SharedPreferences sharedPreferences;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void isSharedPefWorking(){
sharedPreferenceManager.saveString("bis");
assertEquals("bis",sharedPreferenceManager.doSomething());
}
}
SharedPreferences uses a SharedPreferences.Editor which you're not currently mocking.
You would need to do something like the following to mock and verify the behaviour of your SharedPreferenceManager.
#RunWith(MockitoJUnitRunner.class)
public class MockTest {
#InjectMocks
SharedPreferenceManager sharedPreferenceManager;
#Mock
SharedPreferences sharedPreferences;
#Mock
SharedPreferences.Editor sharedPreferencesEditor;
final String savedString = "savedString";
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
when(sharedPreferences.edit()).thenReturn(sharedPreferencesEditor);
when(sharedPreferencesEditor.putString(anyString(), anyString())).thenReturn(sharedPreferencesEditor);
}
#Test
public void saveString() {
sharedPreferenceManager.saveString(savedString);
verify(sharedPreferencesEditor).putString("s", savedString);
}
#Test
public void getString() {
when(sharedPreferences.getString("s","")).thenReturn(savedString);
String preferenceString = sharedPreferenceManager.doSomething();
assertEquals(preferenceString, savedString);
}
}

JUnit Tests for Liferay MVCPortlet using PowerMock

Im trying to make JUnit Test using PowerMock, but I have one problem. Here is my code:
public class MyGreeting extends MVCPortlet {
public static final String GREETING="greeting";
private static final String DEFAULT_GREETING="MY DEFAULT GREETING MESSAGE";
private static final Log _log = LogFactoryUtil.getLog(MyGreeting.class.getName());
#Override
public void render(RenderRequest req,RenderResponse res)
throws IOException, PortletException {
PortletPreferences prefs = req.getPreferences();
req.setAttribute(GREETING, prefs.getValue(GREETING, DEFAULT_GREETING));
super.render(req,res);
}
And I need to make JUnit test. I created another test package, new MyGreetingTest.java file, and come up to this code:
public class MyGreetingTest extends Mockito{
#BeforeClass
public static void setUpBeforeClass() throws Exception {
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
}
private MyGreeting portlet;
#Before
public void setUp() throws Exception {
portlet = new MyGreeting();
}
#After
public void tearDown() throws Exception {
}
#Mock
public RenderRequest request = mock(RenderRequest.class);
#Mock
PortletPreferences preferences = mock(PortletPreferences.class);
#Test
public final void renderTest() throws IOException, PortletException {
when(request.getPreferences()).thenReturn(preferences);
when(preferences.getValue(MyGreeting.GREETING, null)).thenReturn(value);
portlet.render(request, null);
String result = request.getAttribute(MyGreeting.GREETING).toString();
assertEquals(result, value);
}
But I have NullPointerException, because we can't apply getAttribute method to mock-request. Could you please tell me how to solve this problem? How can I test method with getAttribute method using Mockito?
I think you need to mock your method
Stock stock = mock(Stock.class);
when(stock.getPrice()).thenReturn(100.00); // Mock implementation
when(stock.getValue()).thenCallRealMethod(); // Real implementation