Why Mockito "when" method generate NullpointerException? - junit

Hello Guys I am trying to test my controller but i am getting nullpointException at Mockito "when" method in the class TodoControllerTest.getAllToDos() ( please see the pic ), I dont know why?
#ExtendWith(value ={SpringExtension.class})
#WebMvcTest
public class TodoControllerTest {
#Autowired
MockMvc mockMvc;
#MockBean
private ToDoService toDoService;
#Test
public void getAllToDos() throws Exception {
List<ToDo> toDoList = new ArrayList<ToDo>();
toDoList.add(new ToDo(1L,"Eat Eggs",true));
toDoList.add(new ToDo(2L,"Sleep Twice",true));
when(toDoService.findAll()).thenReturn(toDoList);
mockMvc.perform(MockMvcRequestBuilders.get("/todos")
.contentType(MediaType.APPLICATION_JSON)
).andExpect(jsonPath("$", hasSize(2))).andDo(print());
}
}
#Service
public class ToDoService {
public List<ToDo> findAll() {
return new ArrayList<ToDo>();
}
}

It works fine when I use #RunWith(SpringRunner.class) instead #ExtendWith(value ={SpringExtension.class})
because the prject with JUnit4

Related

How to rollback Rabbit-mq message after Junit test?

When you test your code, you send a message to rabbit-mq. How do you get the message back when the test is over?
public interface RabbitProducer {
String OUTPUT = "rabbitmq_producer_channel";
#Output(OUTPUT)
MessageChannel output();
}
public class SysGroupServiceImpl {
#Autowired
private RabbitProducer rabbitProducer;
#Override
public Result remove(Collection<? extends Serializable> idList) {
rabbitProducer.output().send(MessageBuilder.withPayload(idList)
.setHeader("x-delay", 5000)
.setHeader("MessageType", "GroupBatchDelete").build());
return Result.booleanResult(true);
}
}
#SpringBootTest
#Transactional
#Rollback
public class SysGroupServiceTest {
#Autowired
private SysGroupService sysGroupService;
#Test
void removeTest(){
sysGroupService.remove(Stream.of("1").collect(Collectors.toList()));
}
}
I use Spring Cloud Stream to be compatible with RabbitMQ, and all the relevant code is there.Is there a way to mock this out?I tried the following scheme, but due to X-dealy, I got this error:No exchange type x-delayed-message
<dependency>
<groupId>com.github.fridujo</groupId>
<artifactId>rabbitmq-mock</artifactId>
</dependency>
#Component
public class RabbitMqMock {
#Bean
public ConnectionFactory connectionFactory() {
return new CachingConnectionFactory(MockConnectionFactoryFactory.build());
}
}
I know little about mocks. Can mocks create an X-delay exchange?

Mocking object from another class

I have a service class that starts a service.
This service should only start between a certain time.
So i need to mock this , but it does not work.
My Time class:
public boolean isTimeBetween_00_06(){
return Instant.now().isBefore(Instant.now()
.truncatedTo(ChronoUnit.DAYS)
.plus(6,ChronoUnit.HOURS));
}
My Service class:
start(){
if(! new MyTimeUtils().isTimeBetween_00_06){
throw new Exception;
}
}
My test class:
#InjectMocks
private MyServiceClass service;
#Mock
private MyTimeUtils myTimeUtils;
#Test
myTest(){
Mockito.when(myTimeUtils.isCurrentTimeBetween_00_06()).thenReturn(true);
service.start();
}
I expect that I get the right assert, but it stops with Exption.
I also tryed PowerMockito but still it did not work.
Someone have an idea?
Best Regards.
You should inject MyTimeUtils instead of instance creation in the method.
And don't forget #RunWith(MockitoJUnitRunner.class);
Have a look at the code, please:
public class MyServiceClass {
private final MyTimeUtils myTimeUtils;
public MyServiceClass(MyTimeUtils myTimeUtils) {
this.myTimeUtils = myTimeUtils;
}
public void start() {
if (!myTimeUtils.isTimeBetween_00_06()) {
throw new IllegalStateException("ERROR");
}
}
}
#RunWith(MockitoJUnitRunner.class)
public class MyServiceClassTest {
#InjectMocks
private MyServiceClass service;
#Mock
private MyTimeUtils myTimeUtils;
#Test
public void myTest(){
Mockito.when(myTimeUtils.isTimeBetween_00_06()).thenReturn(true);
service.start();
}
}

Mocking an injected object in a method return and UnsupportedOperationException method

I have a class that returns an injected object using Mockito. Everytime I test it, it returns a bull. How would I properly test it to return the correct object?
My class to test:
#Component
public class CarImpl {
#Inject
private Engine v6EngineImpl;
public Engine getEngine() {
return v6EngineImpl;
}
public Exhaust getExhaust() {
throw new UnsupportedOperationException("unsupported");
}
}
Tests:
#RunWith(MockitoJUnitRunner.class)
public class CarTest {
#InjectMocks
private CarImpl carImpl;
#Mock
private Engine v6EngineImpl;
#Test
public void testGetEngine(){
Engine v6EngineImpl = mock(V6EngineImpl.class);
Engine engine = carImpl.getEngine();
// always returns a bull no matter what, how to mock inject.
//return object correctly?
Assert.assertNotNull(engine);
}
#Test
public void testGetExhaust() {
// how to test thrown exception?
}
}
Thanks, I am not too familiar thanks
Try this:
#RunWith(MockitoJUnitRunner.class)
public class CarTest {
#InjectMocks
private CarImpl carImpl;
#Mock
private Engine v6EngineImpl;
#Test
public void testGetEngine(){
Engine engine = carImpl.getEngine();
//engine is the mock injected to CarImpl
Assert.assertNotNull(engine);
Assert.assertSame(engine,v6EngineImpl);
}
#Test(expected=UnsupportedOperationException.class)
public void testGetExhaust() {
carImpl.getExhaust();
}
}

How to write JUnit Test case

I am learning Junit testing on spring boot Application. my account controller method is depend on service class method. For that I used Mockito. I tried simple But here I am not getting how to write test case for following method? How I can use mockito.
can any one please help me for writing this test case?
AccountController
#RestController
#RequestMapping("/spacestudy/$ {InstituteIdentifier}/admin/account")
public class AccountController {
#Autowired
AccountService accService;
#GetMapping("/findAccountData")
public ResponseEntity<List<Tuple>> populateGridViews(#RequestParam(value="sClientAcctId",required=false) String sClientAcctId,
#RequestParam(value="sAcctDesc",required=false) String sAcctDesc,
#RequestParam(value="sInvestigatorName",required=false)String sInvestigatorName,
#RequestParam(value="sClientDeptId",required=false) String sClientDeptId) throws Exception {
return ResponseEntity.ok(accService.populateGridViews(sClientAcctId, sAcctDesc,sInvestigatorName,sClientDeptId));
}
}
AccountService
public List<Tuple> populateGridViews(String sClientAcctId, String sAcctDesc, String sInvestigatorName,
String sClientDeptId)throws Exception{
QAccount account = QAccount.account;
QDepartment department = QDepartment.department;
QAccountCPCMapping accountCPCMapping = QAccountCPCMapping.accountCPCMapping;
QInvestigator investigator = QInvestigator.investigator;
JPAQuery<Tuple> query = new JPAQuery<Tuple>(em);
query.select(Projections.bean(Account.class, account.sClientAcctId, account.sAcctDesc, account.sLocation,
Projections.bean(Department.class, department.sDeptName, department.sClientDeptId).as("department"),
Projections.bean(Investigator.class, investigator.sInvestigatorName).as("investigator"),
Projections.bean(AccountCPCMapping.class, accountCPCMapping.sCCPCode).as("accountCPC"))).from(account)
.innerJoin(account.department, department).innerJoin(account.accountCPC, accountCPCMapping)
.innerJoin(account.investigator, investigator);
if (StringUtils.isNotEmpty(sClientAcctId)) {
query.where(account.sClientAcctId.equalsIgnoreCase(sClientAcctId));
}
// code.......
return query.fetch();
}
AccountControllerTest
#RunWith(SpringRunner.class)
public class TestAccountController {
private MockMvc mockMvc;
#Mock
private AccountService accountService;
#InjectMocks
private AccountController accountController;
#Before
public void setup() {
mockMvc = MockMvcBuilders.standaloneSetup(accountController).build();
}
#Test
public void populateGridViewsTest() throws Exception {
//????
//????
}
}
It will be something like this:
#RunWith(SpringRunner.class)
public class TestAccountController {
private MockMvc mockMvc;
#Mock
private AccountService accountService;
#InjectMocks
private AccountController accountController;
#Before
public void setup() {
mockMvc = MockMvcBuilders.standaloneSetup(accountController).build();
}
#Test
public void populateGridViewsTest() throws Exception {
when(accountService.populateGridViews("foo","bar")).thenReturn(Arrays.asList(new Tuple("bazz"));
mockMvc.perform(get("/spacestudy/STACKOVERFLOW/admin/account/foo/bar"))
.andExpect(status().isOk())
.andExpect(jsonPath("someField").value("bazz"));
}
}
So basically you are replacing your service with mock and saying what it should return. In your particular case I don't see any reasons for unit testing this class, since it doesn't have any logic inside. But if you would have something like:
#GetMapping("/findAccountData")
public ResponseEntity<List<Tuple>> populateGridViews(...) throws Exception {
List<Tuple> result = accService.populateGridViews(...);
if(result==null){
return ResponseEntity.notFound();
}
return ResponseEntity.ok(result);
}
Then it would make more sense to test this class e.g.
1st test - mock your accService to return null and verify that response status is 404
2nd test - mock your accService to return not null and verify that response status is 200

Performing a custom action when a given mocked void method is called

I would like to be able for Mockito to perform a custom action when a given void method is called.
Say I have the following code:
#Autowired
private ProfileService profileService;
#Autowired
private ProfileDao profileDao;
private List<Profile> profiles;
#Before
public void setup() {
Mockito.when(profileDao.findAll()).thenReturn(profiles);
Mockito.when(profileDao.persist(any(Profile.class))).thenAddProfileToAboveList...
}
#Configuration
public static class testConfiguration {
#Bean
public ProfileDao ProfileDao() {
return mock(ProfileDao.class);
}
}
Say I want to add a Profile instance to the profiles list. Can Mockito do that? If so how?
Use Mockito.doAnswer.
doAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) {
// make the changes you need here
}})
.when(mock).someMethod();