jmockit mocking a jacax.sql.DataSource - unit-testing

Trying to use jmockit to stub out a javax.sql.DataSource class. Any ideas?
public class MyTest
{
#MockClass(realClass = DataSource.class)
public static class MockDataSource {
}
#Before
public void setup()
{
Mockit.setUpMocks(MockDataSource.class);
}
#Test
public void testCreateGetUpdateUser()
{
new NonStrictExpectations()
{
...
};
...
}
}
I run the test in eclipse and get this
java.lang.IllegalArgumentException: Not a modifiable class: javax.sql.DataSource
at mockit.internal.RedefinitionEngine.createClassReaderForRealClass(RedefinitionEngine.java:222)
at mockit.internal.RedefinitionEngine.modifyRealClass(RedefinitionEngine.java:207)
at mockit.internal.RedefinitionEngine.redefineMethods(RedefinitionEngine.java:199)
at mockit.internal.RedefinitionEngine.redefineMethods(RedefinitionEngine.java:193)
at mockit.Mockit.setUpMocks(Mockit.java:274)
at MyTest.setup(EntityManagerUTest.java:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.internal.runners.MethodRoadie.runBefores(MethodRoadie.java:122)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

I am not a user of jmockit (I prefer http://mockito.org/ which seems simpler to use), but I think that your #MockClass is not complete - mabybe you need a #Mock method in it:
http://jmockit.googlecode.com/svn/trunk/www/tutorial/StateBasedTesting.html#interfaces

Related

Cannot be cast to java.util.List error while doing caching

I am doing a simple caching in my springboot application. Here I am trying to perform findall,delete and update operations with JPA. At the same time I am trying to update my cache also after performing each operations.
This is my entity
#Entity
#Table(name = "cars")
public class Cars implements Serializable{
#Id
#Column(name = "carId")
private long carId;
#Column(name = "name")
private String name;
..........getters and setters.......
This is my service
#Service
public class CarServiceImpl implements CarService{
#Autowired
private CarRepository carRepo;
#Override
#Transactional
#Cacheable(value = "cars")
public Cars save(Cars car) {
// TODO Auto-generated method stub
System.out.println("reciving from DB for save");
return carRepo.save(car);
}
#Override
#Transactional
#CacheEvict(value="cars" ,key="#id")
public void delete(long id) {
System.out.println("reciving from DB for delete");
// TODO Auto-generated method stub
carRepo.deleteById(id);
}
#Override
#Transactional
#CachePut(value="cars",key="#id")
public Cars update(Cars car,long id) {
System.out.println("reciving from DB for update");
// TODO Auto-generated method stub
return carRepo.save(car);
}
#Override
#Transactional
#Cacheable(value="cars",key="#id")
public List<Cars> getAll(long id) {
System.out.println("reciving from DB for show");
// TODO Auto-generated method stub
return carRepo.findAll();
}
this is the error I am getting when I perform update operation to add a new entity and then call getAll method where it loads from cache .
java.lang.ClassCastException: com.example.springCaching.entity.Cars cannot be cast to java.util.List
at com.example.springCaching.serviceImpl.CarServiceImpl$$EnhancerBySpringCGLIB$$80d45199.getAll(<generated>) ~[classes/:na]
at com.example.springCaching.contoller.CarController.show(CarController.java:39) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_161]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_161]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_161]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_161]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:893) ~[spring-webmvc-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:798) ~[spring-webmvc-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.1.14.RELEASE.jar:5.1.14.RELEASE]
at org.springframework.web.se

powermockito spy private void method invocation

For a test class with a private void method, what is the right way to mock the behaviour of the method. The solution below invokes the method instead.
public class TestWizard {
private void testOne(){
throw new NullPointerException();
}
private void testTwo(){
testOne();
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest({TestWizard.class})
public class WTest {
#Test
public void testWizard() throws Exception {
TestWizard wizard2 = Whitebox.newInstance(TestWizard.class);
TestWizard wizard = Mockito.spy(wizard2);
PowerMockito.doNothing().when(wizard, "testTwo");
}
}
The error is:
java.lang.NullPointerException
at tuk.pos.wizard.model.TestWizard.testOne(TestWizard.java:6)
at tuk.pos.wizard.model.TestWizard.testTwo(TestWizard.java:10)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:1862)
at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:824)
at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:689)
at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:401)
at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:105)
Use PowerMockito.spy(...) instead of Mockito.spy(...).
Tested with PowerMockito 2.0.5
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
#RunWith(PowerMockRunner.class)
#PrepareForTest(WTest.TestWizard.class)
public class WTest {
public class TestWizard {
private void testOne(){
throw new NullPointerException();
}
private void testTwo(){
testOne();
}
}
#Test
public void testWizard() throws Exception {
TestWizard spy = PowerMockito.spy(Whitebox.newInstance(TestWizard.class));
PowerMockito.doNothing().when(spy, "testTwo");
spy.testTwo();
}
}
Try to restrict the usage of spies to legacy code. In most other cases a refactoring should be the preferred solution.

Mockito junit testing not working- beans mocked by #mockBean are null

I am trying Mockito for mocking and unit testing.
Trying to mock an autowired bean using #MockBean. But the bean is null at run time.
Class under test.
#Service
public class UserServiceImpl {
#Autowired
GenericRestClient restClient;
#Autowired
RequestMapper requestMapper;
#Autowired
ResponseMapper responseMapper;
#Override
public List<User> findUsers(RRequest requestBody,
String index) throws HostException {
List<User> users=
requestMapper.mapRequest("test");
// ...doing something
return users;
}
The test class :
import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.boot.test.mock.mockito.MockBean;
#RunWith(MockitoJUnitRunner.class)
public class UserServiceImplTest {
#MockBean
GenericRestClient restClient;
#MockBean
RequestMapper requestMapper;
#MockBean
ResponseMapper responseMapper;
#InjectMocks
UserServiceImpl userService;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testFindUsers() {
List<Users> users = null;
Mockito.when(requestMapper.mapRequest("test"))
.thenReturn(users);
assertNull(users);
}
}
Error :
java.lang.NullPointerException
at test.my.code.UserServiceImplTest.testFindUsers(UserServiceImplTest.java:10)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
I have debugged, NullPointerException is because of requestMapper (mocked using MockBean as it is null.)
What is wrong with this code?
Unlike #abinmichael I don't suggest using Spring Runner to run this test. Your test is a unit test, and running Spring (creating an application context) is a very expensive operation, more suitable for integration testing.
I'm not a mockito expert, but I believe, you should refactor slightly the UserServiceImpl so that the dependencies will become visible:
#Service
public class UserServiceImpl {
private final GenericRestClient restClient;
private final RequestMapper requestMapper;
private final ResponseMapper responseMapper;
#Autowired // in recent spring version, this annotation can be omitted
public UserServiceImpl(GenericRestClient restClient, RequestMapper requestMapper, ResponseMapper responseMapper) {
this.restClient = restClient;
this.requestMapper = requestMapper;
this.responseMapper = responseMapper;
}
...
With such an approach there is no need in #InjectMocks anymore:
#RunWith(MockitoJUnitRunner.class)
public class UserServiceImplTest {
#Mock
GenericRestClient restClient;
#Mock
RequestMapper requestMapper;
#Mock
ResponseMapper responseMapper;
UserServiceImpl userService;
#Before
public void init() {
userService = new UserServiceImpl(restClient, requestMapper, responseMapper);
}
....
}
If you insist on using fields injection, read The accepted answer to get more information about how does #InjectMocks work. Maybe you don't have "private" access modifier, maybe you have some mix between Constructor injection and field injection and #InjectMocks doesn't not support both simultaneously
I suggest you can try this approach, using #InjectMocks for the test target and use #Mock for injected classes inside that service.
No need to use #Before since you used field injection.
#RunWith(SpringRunner.class)
#SpringBootTest(classes = YourMainClass.class)
public class UserServiceImplTest {
#Mock
GenericRestClient restClient;
#Mock
RequestMapper requestMapper;
#Mock
ResponseMapper responseMapper;
#InjectMocks
UserServiceImpl userService
#Test
public void testFindUsers() {
}
}
Can you try running the test after changing to
#RunWith(SpringRunner.class)
#SpringBootTest
public class UserServiceImplTest {
The javadoc https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/mock/mockito/MockBean.html
states
#Target(value={TYPE,FIELD})
#Retention(value=RUNTIME)
#Documented
#Repeatable(value=MockBeans.class)
public #interface MockBean
Annotation that can be used to add mocks to a Spring ApplicationContext. Can be used as a class level annotation or on fields in either #Configuration classes, or test classes that are #RunWith the SpringRunner.

JUnit test case: java.lang.NullPointerException

I am trying to write test case for following controller code using JUnit and mockito. But I am getting null pointer Exception. I am new to JUnit testing. can any one please tell what I am doing wrong here?
DepartmentController
#RestController
#RequestMapping("/api.spacestudy.com/SpaceStudy")
public class DepartmentController {
#Autowired
DepartmentService depService;
#CrossOrigin(origins = "http://localhost:4200")
#GetMapping("/LoadDept")
public Department findDeptId() {
return depService.findDeptId();
}
}
DepaermentControllerTest
#WebMvcTest
public class DepartmentControllerTest {
#Autowired
private MockMvc mockMvc;
#Mock
public DepartmentService depService;
#InjectMocks
DepartmentController departmentController;
#Before
public void setup() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(departmentController).build();
}
#Test
public void findDeptIdTest() throws Exception
{
Department department = new Department();
department.setnDeptId(10);
Mockito.when(depService.findDeptId()).thenReturn(department);
mockMvc.perform(get("/api.spacestudy.com/SpaceStudy/LoadDept").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.nDeptId", Matchers.is(10)));
}
}
Test Result
java.lang.NullPointerException
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.detectHandlerMethods(AbstractHandlerMethodMapping.java:227)
at org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder$StaticRequestMappingHandlerMapping.registerHandlers(StandaloneMockMvcBuilder.java:490)
at org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder.registerMvcSingletons(StandaloneMockMvcBuilder.java:356)
at org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder.initWebAppContext(StandaloneMockMvcBuilder.java:341)
at org.springframework.test.web.servlet.setup.AbstractMockMvcBuilder.build(AbstractMockMvcBuilder.java:139)
at com.spacestudy.DepartmentControllerTest.setup(DepartmentControllerTest.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
to solve that problem, you have to give an instance of DepartmentController class at standaloneSetup(). I had the same issue while working on some unit testing and after that, my problem disappeared. Try to do it:
#Before
public void setup() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(new DepartmentController()).build();
}

PowerMock(with mockito) simple unit test error

I am using Mockito + PowerMock to write a simple unit test for the following singleton class:
public class MyService {
private static MyService service;
private List<School> schoolList;
private MyService(){
// test case error complains here!
School school = new School();
schoolList.add(school);
}
public static Singleton getInstance( ) {
return service;
}
protected static void printSchool( ) {
School school = schoolList.get(0);
print(school);
}
}
My Test case:
#RunWith(PowerMockRunner.class)
public class MyServiceTest {
#PrepareForTest({MyService.class})
#Test
public void testPrintSchool() {
// enable mock static function
PowerMockito.mockStatic(MyService.class);
MyService mockService = PowerMockito.mock(MyService.class);
PowerMockito.when(MyService.getInstance())
.thenReturn(mockService);
}
}
I run my test, but got the following error:
java.lang.RuntimeException: Invoking the beforeTestMethod method on PowerMock test listener org.powermock.api.extension.listener.AnnotationEnabler#3ab19451 failed.
at com.xyz.MyService.<init>(MyService.java:12)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.mockito.internal.util.reflection.FieldInitializer$ParameterizedConstructorInstantiator.instantiate(FieldInitializer.java:257)
at org.mockito.internal.util.reflection.FieldInitializer.acquireFieldInstance(FieldInitializer.java:124)
at org.mockito.internal.util.reflection.FieldInitializer.initialize(FieldInitializer.java:86)
at org.mockito.internal.configuration.injection.ConstructorInjection.processInjection(ConstructorInjection.java:52)
...
As you can see, the error complains about MyService.java:12 line 12, that is the line School school = new School(); in MyService constructor.
Why I get this error, how to get rid of it?
#PrepareForTest({MyService.class}) is a class level annotation.
You should add it at the same location as #RunWith(PowerMockRunner.class)
You can find more information at their github