public class Abcd {
public String one() {
System.out.println("Inside method one");
StringBuilder sb = new StringBuilder();
two(sb);
return "Done";
}
private void two(StringBuilder sb) {
System.out.println("Inside method two");
}
}
Here is the test class
#RunWith(PowerMockRunner.class)
#PrepareForTest(Abcd.class)
public class TestAbcd {
#Test
public void testMethod1() throws Exception {
Abcd abcd = PowerMockito.spy(new Abcd());
StringBuilder sb = new StringBuilder();
PowerMockito.doNothing().when(abcd, "two", sb);
abcd.one();
}
}
Console Output:
Inside method one
Inside method two
No failure trace in edited part:
Failure trace:
Please let me know what mistake i am making, and how can i make it work.
You need #PrepareForTest annotaion to gain such a control on private methods with PowerMockito.
See this article: What does #PrepareForTest in PowerMock really mean?
In summary the test case should look like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest(Abcd.class)
public class TestAbcd {
#Test
public void testMethod1() throws Exception {
Abcd abcd = PowerMockito.spy(new Abcd());
PowerMockito.doNothing().when(abcd, method(Abcd.class, "two", StringBuilder.class))
.withArguments(any(StringBuilder.class));
abcd.one();
}
}
Related
I am trying to spy private method with PowerMock but on the line when I define the what should be returned when the private method is called, it calls the method and I am getting and Null Pointer Exception. What PowerMock is calling real method on this line ?
myService= PowerMockito.spy(new MyService(myParam));
.....
PowerMockito.when(myService, "getCLientBy", anyString(), anyString(), anyString()).thenRetur`n(Client.of(setName, new HashSet<>())); // here it calls real method
Ensure that you prepare your class to be used in spy by adding #PrepareForTest(MyService.class)
#RunWith(PowerMockRunner.class)
// We prepare MyService for test because it's final
// or we need to mock private or static methods
#PrepareForTest(MyService.class)
public class YourTestCase {
//...
#Test
public void spyingWithPowerMock() {
MyService classUnderTest = PowerMockito.spy(new MyService(myParam));
//.....
// use PowerMockito to set up your expectation
PowerMockito.doReturn(Client.of(setName, new HashSet<>()))
.when(classUnderTest, "getClientBy", anyString(), anyString(), anyString());
//...
Also make sure provide the correct method name to be invoked.
#user1474111 and #Nkosi
I've built a small simulation of your example.
Maybe you also need to add the Client class in the PrepareForTest annotation.
#RunWith(PowerMockRunner.class)
#PrepareForTest({ MyService.class, Client.class })
public class Example1Test {
#Test
public void testPowerMockito() throws Exception {
MyService myService = PowerMockito.spy(new MyService("myParam"));
PowerMockito.when(myService, "getClientBy", ArgumentMatchers.anyString(), ArgumentMatchers.anyString(),
ArgumentMatchers.anyString()).thenReturn(Client.of("setName", new HashSet<String>()));
myService.run();
Assert.assertEquals("setName", myService.getClient().getName());
}
}
public class MyService {
private Client client;
public MyService(String param) { }
private Client getClientBy(String a, String b, String c) {
return new Client(a + b + c);
}
public Client getClient() {
return this.client;
}
public void setClient(Client client) {
this.client = client;
}
public void run() {
setClient(getClientBy("A", "B", "C"));
}
}
public class Client {
private final String name;
public Client(String name) {
this.name = name;
}
public static Client of(String name, HashSet<String> hashSet) {
return new Client(name);
}
public String getName() {
return name;
}
}
I recently started reading up about Mockito. The following line of code must return true as per my understanding, but it returns false.
Test Class
public class PersonServiceImplTest {
Car car;
#InjectMocks
CarServiceImpl carService;
#Mock
CarDAOImpl carDAO;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testUpdateCar() {
int carId = 1;
Mockito.when(carDAO.getCarById(any(Integer.class))).thenReturn(new Car());
carService.updateCar(carId);
Mockito.when(carDAO.isLicenseExpired(any(Car.class))).thenReturn(true);
Mockito.verify(carDAO).updateCar(any(Car.class));
Mockito.verify(carDAO, times(1)).isLicenseExpired(any(Car.class));
Mockito.verify(carDAO, times(1)).issueLicense(any(Car.class));
}
}
Class to be tested
public class CarServiceImpl implements CarService {
#Autowired carDAO carDAO;
#Override
public Response updateCar(int carId) {
Car car =carDAO.getCarById(carId);
try {
carDAO.updateCar(car);
if(carDAO.isLicenseExpired(car)))
carDAO.issueLicense(car);
} catch (Exception e) {
log.error(e.getMessage());
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
}
return Response.ok(Status.CREATED).build();
}
CarDAOImpl deals with the database, if needed, will update that too.
Thanks in advance.
These two lines are ordered incorrectly:
carService.updateCar(carId);
Mockito.when(carDAO.isLicenseExpired(Mockito.any(Car.class))).thenReturn(true);
The first line in that pair invokes the class-under-test and the second line sets up an expectation of how your carDAO should behave inside the class-under-test. So, you are setting the expectation after you invoke the class-under-test.
The following test will pass:
#Test
public void testUpdateCar() {
int carId = 1;
// establish expectations of how carDAO should behave inside updateCar()
Mockito.when(carDAO.getCarById(Mockito.any(Integer.class))).thenReturn(new Car());
Mockito.when(carDAO.isLicenseExpired(Mockito.any(Car.class))).thenReturn(true);
// invoke the class-under-test
carService.updateCar(carId);
// verify that CarService used CarDAO correctly
Mockito.verify(carDAO).updateCar(Mockito.any(Car.class));
Mockito.verify(carDAO).isLicenseExpired(Mockito.any(Car.class));
Mockito.verify(carDAO).issueLicense(Mockito.any(Car.class));
}
I have this code in main class -
try {
extraPlayer = gson.fromJson(jsonResponse, ExtraPlayer.class);// this returns null
} catch (Exception e) {
e.printStacktrace();
}
Here extraPlayer is coming as null
I have mocked #Mock Gson gsonMock;
Here ExtraPlayer is a static class.
I have written this test code -
#Test
public void test() {
String jsonResponse = "{\"status\":\"waiting\",\"no\":\"12\"}";
when(playerHandlerMock.resetPlayer("someString", "someString", "1",true
)).thenReturn(jsonResponse);
Gson gsonMock = PowerMockito.mock(Gson.class);
ExtraPlayer extraPlayer = new ExtraPlayer();
extraPlayer.setNo("12");
extraPlayer.setStatus("Waiting");
PowerMockito.mockStatic(ResetModemResponse.class); // using this for static class but didn't work.
PowerMockito.when(gsonMock.fromJson(jsonResponse, ExtraPlayer.class)).thenReturn(extraPlayer);
playerMock.performWaiting();
}
ExtraPlayer.java
public static class ExtraPlayer{
String no;
String status;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getNo() {
return code;
}
public void setNo(String no) {
this.no = no;
}
}
I have added these annotations to the test class -
#RunWith(PowerMockRunner.class)
#PrepareForTest(Gson.class)
why extraPlayer is null ? please help/Suggest.
If you were to use the standard #Mock and #InjectMocks annotation with mockito, then yes, the framework would take care of the injection of the mock into the class under test (regardless of the existence of the setters etc.).
Another thing is the playerMock, which i assume is the class under test.
Do not mock the class under test, create a normal instance and then inject the dependencies... the performWaiting method does not seem to accept the response String, so you would have to inject that also somehow (unless you left some parts out):
#Test
public void test() {
// Arrange
String jsonResponse = "{\"status\":\"waiting\",\"no\":\"12\"}";
Gson gsonMock = PowerMockito.mock(Gson.class);
ExtraPlayer extraPlayer = new ExtraPlayer();
extraPlayer.setNo("12");
extraPlayer.setStatus("Waiting");
PowerMockito.when(gsonMock.fromJson(jsonResponse, ExtraPlayer.class)).thenReturn(extraPlayer);
Player player = new Player();
player.setGson(gsonMock);
player.setResponse(jsonResponse);
// Act
player.performWaiting();
// Assert ...
}
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
I am trying to unit test the log statements generated in my code. I am using slfj, log4j and Mockito. I am using the similar code as below from the blog at
http://bloodredsun.com/2010/12/09/checking-logging-in-unit-tests/
When I run the test it throws exception saying that there are 0 invocations at line:
verify(mockAppender).doAppend(captorLoggingEvent.capture());
Error Message:
Wanted but not invoked: mockAppender.doAppend();
-> at testClass.testLogAdviceAfterReturning(DpsOpsLoggerTest2.java:94) Actually, there were zero interactions with this mock.
I see the logs printed on the console though. Request you to kindly help.
#RunWith(MockitoJUnitRunner.class)
public class ExampleThatLogsTest {
#Mock
private Appender mockAppender;
#Captor
private ArgumentCaptor captorLoggingEvent;
#Before
public void setup() {
LogManager.getRootLogger().addAppender(mockAppender);
}
#After
public void teardown() {
LogManager.getRootLogger().removeAppender(mockAppender);
}
#Test
public void shouldConcatAndLog() {
//given
ExampleThatLogs example = new ExampleThatLogs();
//when
String result = example.concat("foo", "bar");
//then
assertEquals("foobar", result);
verify(mockAppender).doAppend(captorLoggingEvent.capture());
LoggingEvent loggingEvent = captorLoggingEvent.getValue();
//Check log level
assertThat(loggingEvent.getLevel(), is(Level.INFO));
//Check the message being logged
assertThat(loggingEvent.getRenderedMessage(),
is("String a:foo, String b:bar"));
}
}
I tried to emulate your case ,At my end it is working fine
//Log Util
public class LogUtil{
final static Logger logger = Logger.getLogger(LogUtil.class);
public static Log`enter code here`ger getLogger()
{
return logger;
}
//class
public class RunMe {
public String runMe(String parameter) {
LogUtil.getLogger().info("This is info : " + parameter);
return "In runner " + parameter;
}
}
// Unit Test
#RunWith(MockitoJUnitRunner.class)
public class LoggerTest {
#Mock
private Appender mockAppender;
#Captor
private ArgumentCaptor captorLoggingEvent;
#Before
public void setup() {
LogUtil.getLogger().addAppender(mockAppender);
}
#Test
public void shouldConcatAndLog() {
RunMe runner=new RunMe();
String result=runner.runMe("XYZ");
assertEquals("In runner XYZ",result);
verify(mockAppender).doAppend((LoggingEvent) captorLoggingEvent.capture());
LoggingEvent logevent= (LoggingEvent) captorLoggingEvent.getValue();
assertThat(logevent.getLevel(), is(Level.INFO));
}
#After
public void tearDown() {
LogUtil.getLogger().removeAllAppenders();
}
}
I know this is a little bit outdated, but I was struggling with this too. I was logging statements at DEBUG level in the class under test. My configuration in logback.xml for the class under test was set to INFO. Changing my logging statement to INFO allowed the test to pass. In addition, I also read this Github post that is really concise and a clean implementation of testing log output. Hope others will find it useful.