I have written Junit for the service. mocking dao.
Service method return type in EmployeeDTO.
Dao return type is Employee.
problem is employee to employeeDto conversion failed in test case.
when(dao.method()).thenReturn(new Employee), so on call od service.method() I am facing issue since dozer is in between to convert employee to employeedto in the actual code.
any suggestions to fix this.
#SpringBootTest(classes = { EmployeeSearchService.class, EmployeeDao.class })
public class EmployeeSearchServiceTest {
#Mock // will create a mock implementation for the EmployeeDao
EmployeeDao employeeDao;
#InjectMocks // will inject the mocks marked with #Mock to this instance when it is created.
private EmployeeSearchService employeeSearchService ;
#Mock
private DozerBeanMapper dozerBeanMapper;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#DisplayName("fetchEmployees with valid data")
#Test
public void testfetchEmployeesWithValidData() throws IOException {
when(employeeDao.fetchEmployees()).thenReturn(Stream
.of(new Employee((long) 1, "James", "Java", "Manager", "Google"),
new Employee((long) 2, "Richard", "C++", "Manager", "Microsfot"))
.collect(Collectors.toList()));
//when(dozer.map(Mockito.any(), Mockito.any())).thenReturn(employeeDTO);
System.out.println(employeeSearchService.fetchEmployees());
assertEquals(4, employeeSearchService.fetchEmployees().size());
}
}
#Service
public class EmployeeSearchServiceImpl implements EmployeeSearchService {
#Autowired
EmployeeDao employeeDao;
#Autowired
DozerBeanMapper dozerBeanMapper;
#Override
#Logging
public List<EmployeeDTO> fetchEmployees() throws IOException {
List<Employee> aEmployeeList = employeeDao.fetchEmployees();
List<EmployeeDTO> aEmployeeDTOList= aEmployeeList.stream().map(emp ->
dozerBeanMapper.map(emp,
EmployeeDTO.class)).collect(Collectors.toList());
if (aEmployeeList.isEmpty()) {
throw new EmployeeNotfoundException("Employee Details Not Available");
}
return aEmployeeDTOList;
}
}
#Repository
public class EmployeeDaoImpl implements EmployeeDao {
#Override
#Logging
public List<Employee> fetchEmployees() throws IOException {
List<String> aFileList=fileUtils.getFileContent(EmployeeSearchConstants.EMPLOYEE_DETAILS_PATH);
List<Employee> aEmployeList = getEmployee(aFileList);
if (aEmployeList.isEmpty()) {
throw new EmployeeNotfoundException("Employee Details Not Available");
}
return aEmployeList;
}
}
If I understand you correctly your issue is that you are looking for a way to convert your Employee into a EmployeeDTO object, which in your code is done using dozerBeanMapper.map(emp, EmployeeDTO.class).
One option would be to change the EmployeeSearchServiceImpl and use Constructor Injection instead of Field Injection. This way you could simply use the real dozer class to do the mapping (by manually passing the mock for employeeDao and the real dozerBeanMapper).
Constructor Injection is done by moving the #Autowired to the constructor instead of the fields. Depening on your spring version and in case you only have one constructor for the class you might be able to omit the annotation. For more information check here.
EmployeeDao employeeDao;
DozerBeanMapper dozerBeanMapper;
#Autowired
public EmployeeSearchServiceImpl(EmployeeDao employeeDao, DozerBeanMapper dozerBeanMapper) {
this.employeeDao = employeeDao;
this.dozerBeanMapper = dozerBeanMapper;
}
Another option would be to use Mockito's thenAnser functionality. However
you still require something to do the conversion for you.
when(dozerBeanMapper.map(Mockito.any(), Mockito.any())).thenAnswer(new Answer<EmployeeDTO>() {
public EmployeeDTO answer(InvocationOnMock invocation) {
Employee employee = (Employee) invocation.getArguments()[0];
// convert to EmployeeDTO
EmployeeDTO dto = ...
return dto;
}
});
Related
I am having dificulties with using MockMvc.
Here I have simple Service and controller classes:
Service:
#Slf4j
#Service
public class EmployeeService {
//...
public Employee GetSample() {
//...
//filling Employee Entities
return new Employee(
"Harriet"
, "random"
, 25);
}
}
controller:
#RestController
#RequestMapping(value = "/info")
#RequiredArgsConstructor(onConstructor = #__(#Autowired))
#Validated
public class EmployeeController {
private final EmployeeService employeeService;
#PostMapping("/GetEmployee")
public ResponseEntity<Employee> GetEmployee() {
Employee employee = employeeService.GetSample();
return new ResponseEntity<>(employee, HttpStatus.OK);
}
}
Test:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest
public class EmployeeTestCase {
private MockMvc mockMvc;
#InjectMocks
private EmployeeController EmployeeController;
#Mock
private EmployeeService employeeService;
#Before
public void setUp() {
this.mockMvc = MockMvcBuilders.standaloneSetup(employeeController).build();
}
#Test
public void getEmployee() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.post("/info/GetEmployee")).andDo(print());
}
}
when I try to use MockMvc I get null body. It seems employee is null. But I didn't understand why.
I thought that when test uses perform, it should initialise employee and later on it should't be null.
I tried to cut the code as much as possible. I hope it is not long.
Note : also tried to use Mockito.when(employeeController.GetEmployee()).thenCallRealMethod();
The #SpringBootTest annotation loads the complete Spring application
context. That means you do not mock your layers
(Services/Controllers).
If you wanted to test specific layers of your application, you could look into test slice annotations offered by Springboot: https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html
In contrast, a test slice annotation only loads beans required to test a particular layer. And because of this, we can avoid unnecessary mocking and side effects.
An example of a Test Slice is #WebMvcTest
#ExtendWith(SpringExtension.class)
#WebMvcTest(controllers = HelloController.class,
excludeFilters = {
#ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = SecurityConfig.class)
}
)
public class HelloControllerTest {
#Autowired
private MockMvc mvc;
#Test
public void hello() throws Exception {
String hello = "hello";
mvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string(hello));
}
#Test
public void helloDto() throws Exception {
String name = "hello";
int amount = 1000;
mvc.perform(
get("/hello/dto")
.param("name", name)
.param("amount", String.valueOf(amount)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name", is(name)))
.andExpect(jsonPath("$.amount", is(amount)));
}
}
However if you really wanted to load up the SpringBoot Application context, say for an Integration Test, then you have a few options:
#SpringBootTest
#AutoConfigureMockMvc
public class TestingWebApplicationTest {
#Autowired
private MockMvc mockMvc;
#Test
public void shouldReturnDefaultMessage() throws Exception {
this.mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk())
.andExpect(content().string(containsString("Hello, World")));
}
}
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest
public class AuctionControllerIntTest {
#Autowired
AuctionController controller;
#Autowired
ObjectMapper mapper;
MockMvc mockMvc;
#Before
public void setUp() throws Exception {
System.out.println("setup()...");
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
#Test
public void create_ValidAuction_ShouldAddNewAuction() throws Exception {
final Auction auction = new Auction(
"Standing Desk",
"Stand up desk to help you stretch your legs during the day.",
"Johnnie34",
350.00);
mockMvc.perform(post("/auctions")
.contentType(MediaType.APPLICATION_JSON)
.content(toJson(auction)))
.andExpect(status().isCreated());
}
}
Lets say you don't want to load up any layers at all, and you want to mock everything, such as for example a Unit Test:
#RunWith(MockitoJUnitRunner.class)
class DemoApplicationTest {
#Mock
private UserRepository userRepository;
private Demo noneAutoWiredDemoInstance;
#Test
public void testConstructorCreation() {
MockitoAnnotations.initMocks(this);
Mockito.when(userRepository.count()).thenReturn(0L);
noneAutoWiredDemoInstance = new Demo(userRepository);
Assertions.assertEquals("Count: 0", noneAutoWiredDemoInstance.toString());
}
}
I would like to create Test for my rest controller:
#Controller
#RequestMapping("/v2/api/show/project")
public class ApiAccessController {
private final ApiAccessService apiAccessService;
#Autowired
ApiAccessController(ApiAccessService apiAccessService){
this.apiAccessService = apiAccessService;
}
#PutMapping(value = "/{id}/apikey")
public ResponseEntity<ApiKeyResponse> generateApiKey(#PathVariable("id")Long id, Principal principal) {
return apiAccessService.generateApiKey(id, principal.getName());
}
}
My test looks as follow:
#RunWith(SpringJUnit4ClassRunner.class)
public class ApiAccessControllerTest {
private MockMvc mockMvc;
Principal principal = new Principal() {
#Override
public String getName() {
return "TEST_PRINCIPAL";
}
};
#InjectMocks
ApiAccessController apiAccessController;
#Mock
ProjectRepository projectRepository;
#Before
public void setUp(){
mockMvc = MockMvcBuilders.standaloneSetup(apiAccessController).build();
}
#Test
public void testGenerateApiKey() throws Exception {
Project project = new Project();
project.setId((long) 1);
project.setName("test");
project.setDescription("testdesc");
project.setCiid("ciid");
when(projectRepository.save(any(Project.class))).thenReturn(project);
mockMvc.perform(MockMvcRequestBuilders.put("/v2/api/show/project/" + project.getId() +"/apikey").principal(principal))
.andExpect(MockMvcResultMatchers.status().isOk());
}
}
Which is ment to create project and then run generateApiKey on this project, however I get NullpointerException looking like mocked controller cannot find created entity
could anyone please point me in the right direction as I am just starting with testing?
You should mock ApiAccessService instead of ProjectRepository.
Have a look at the code:
#RunWith(SpringJUnit4ClassRunner.class)
public class ApiAccessControllerTest {
private MockMvc mockMvc;
private Principal principal = () -> "TEST_PRINCIPAL";
#InjectMocks
private ApiAccessController apiAccessController;
#Mock
private ApiAccessService apiAccessService;
#Before
public void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(apiAccessController).build();
}
#Test
public void testGenerateApiKey() throws Exception {
long id = 1L;
when(apiAccessService.generateApiKey(id, principal.getName())).thenReturn(new ApiKeyResponse(111L));
mockMvc.perform(MockMvcRequestBuilders.put("/v2/api/show/project/{id}/apikey", id).principal(principal))
.andExpect(MockMvcResultMatchers.status().isOk());
}
}
If you want to create integration test, that tests ApiAccessController -> ApiAccessService -> ProjectRepository integration you need to load your context (use for example #SpringBootTest).
Also you need to fix controller, use ResponseEntity.ok(...) :
#PutMapping(value = "/{id}/apikey")
public ResponseEntity<ApiKeyResponse> generateApiKey(#PathVariable("id") Long id, Principal principal) {
return ResponseEntity.ok(apiAccessService.generateApiKey(id, principal.getName()));
}
You can find really good examples of all test types in this repository MVC tests examples
The Mock you are creating is not referenced in the Controller. The Service you reference in the Controller is not part of your test setup. Therefore any access to the Service will cause a NullPointerException as the Service is not set.
I set up following pact contract provider test
#RunWith(SpringRestPactRunner.class)
#Provider("structures")
#PactFolder("pacts")
#VerificationReports({"console", "markdown"})
#SpringBootTest
public class ContractTest {
#MockBean
private MyServiceImpl myServiceImpl;
#Autowired
private MyController myController;
#Configuration
public static class TestConfiguration {
#Bean
public MyController myController() {
return new MyController();
}
}
#TestTarget
public final MockMvcTarget target = new MockMvcTarget();
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
target.setControllers(myController);
}
#State("My state")
public void setupDocumentWithStructures() {
Mockito.when(myService.getStructuresByDocumentId(
ArgumentMatchers.eq("1"),
ArgumentMatchers.any()
)).thenReturn(new PageImpl<>(Arrays.asList(
Structure.of("first"),
Structure.of("second")
)));
}
}
Running the test results in:
java.lang.AssertionError:
0 - Request processing failed; nested exception is java.lang.IllegalStateException: No primary or default constructor found for interface org.springframework.data.domain.Pageable
java.lang.IllegalStateException: No primary or default constructor found for interface org.springframework.data.domain.Pageable
The method getStructuresByDocumentId expects a Pageable object as its second argument. Changing the annotation #SpringBootTest to
#WebMvcTest(MyController.class)
#EnableSpringDataWebSupport
Doesn't solve the problem. Any ideas, how to solve this issue?
you used "myService" in your setupDocumentWithStructures whereas your #MockBean is myServiceImpl.......I think you meant to use myServiceImpl in setupDocumentWithStructures
That's how it can work
#Before
public void setupOrInit() {
this.mockMvc = MockMvcBuilders.standaloneSetup(controller)
.setControllerAdvice(new ErrorRequestInterceptor(tracer))
.setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
.build();
}
I was having the same problem and fixed setting a new mockMvc like this
#Before
public void before() {
MockitoAnnotations.initMocks(this);
target.setMockMvc(MockMvcBuilders.standaloneSetup(myController)
.setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
.build());
}
I am not using #SpringBootTest as you are, but I think in this case it does not matter. Below is my entire (redacted) code.
#RunWith(SpringRestPactRunner.class)
#Provider("my-provider")
#PactBroker(url = "https://pact-broker.my-compnay.com")
public class MyControllerProviderContractTest {
#TestTarget
public final MockMvcTarget target = new MockMvcTarget();
#Mock
private MyService myService;
#InjectMocks
private MyController myController = new MyController();
#Before
public void before() {
MockitoAnnotations.initMocks(this);
target.setMockMvc(MockMvcBuilders.standaloneSetup(myController)
.setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
.build());
}
#State("my state")
public void stateForMyMethod() {
//my mocks
}
}
I hope this helps, I spend a few hours trying to solve this.
Cheers
In normal Spring, when we want to autowire an interface, we define it's implementation in Spring context file.
What about Spring boot?
how can we achieve this?
currently we only autowire classes that are not interfaces.
Another part of this question is about using a class in a Junit class inside a Spring boot project.
If we want to use a CalendarUtil for example, if we autowire CalendarUtil, it will throw a null pointer exception. What can we do in this case? I just initialized using "new" for now...
Use #Qualifier annotation is used to differentiate beans of the same interface
Take look at Spring Boot documentation
Also, to inject all beans of the same interface, just autowire List of interface
(The same way in Spring / Spring Boot / SpringBootTest)
Example below:
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
public interface MyService {
void doWork();
}
#Service
#Qualifier("firstService")
public static class FirstServiceImpl implements MyService {
#Override
public void doWork() {
System.out.println("firstService work");
}
}
#Service
#Qualifier("secondService")
public static class SecondServiceImpl implements MyService {
#Override
public void doWork() {
System.out.println("secondService work");
}
}
#Component
public static class FirstManager {
private final MyService myService;
#Autowired // inject FirstServiceImpl
public FirstManager(#Qualifier("firstService") MyService myService) {
this.myService = myService;
}
#PostConstruct
public void startWork() {
System.out.println("firstManager start work");
myService.doWork();
}
}
#Component
public static class SecondManager {
private final List<MyService> myServices;
#Autowired // inject MyService all implementations
public SecondManager(List<MyService> myServices) {
this.myServices = myServices;
}
#PostConstruct
public void startWork() {
System.out.println("secondManager start work");
myServices.forEach(MyService::doWork);
}
}
}
For the second part of your question, take look at this useful answers first / second
You can also make it work by giving it the name of the implementation.
Eg:
#Autowired
MyService firstService;
#Autowired
MyService secondService;
Assume that you have a GreetingService
public interface GreetingService {
void doGreetings();
}
And you have 2 implementations HelloService
#Service
#Slf4j
public class HelloService implements GreetingService{
#Override
public void doGreetings() {
log.info("Hello world!");
}
}
and HiService
#Slf4j
#Service
public class HiService implements GreetingService{
#Override
public void doGreetings() {
log.info("Hi world!");
}
}
Then you have another interface, which is BusinessService to call some business
public interface BusinessService {
void doGreetings();
}
There are some ways to do that
#1. Use #Autowired
#Component
public class BusinessServiceImpl implements BusinessService{
#Autowired
private GreetingService hiService; // Spring automatically maps the name for you, if you don't want to change it.
#Autowired
private GreetingService helloService;
#Override
public void doGreetings() {
hiService.doGreetings();
helloService.doGreetings();
}
}
In case you need to change your implementation bean name, refer to other answers, by setting the name to your bean, for example #Service("myCustomName") and applying #Qualifier("myCustomName")
#2. You can also use constructor injection
#Component
public class BusinessServiceImpl implements BusinessService {
private final GreetingService hiService;
private final GreetingService helloService;
public BusinessServiceImpl(GreetingService hiService, GreetingService helloService) {
this.hiService = hiService;
this.helloService = helloService;
}
#Override
public void doGreetings() {
hiService.doGreetings();
helloService.doGreetings();
}
}
This can be
public BusinessServiceImpl(#Qualifier("hiService") GreetingService hiService, #Qualifier("helloService") GreetingService helloService)
But I am using Spring Boot 2.6.5 and
public BusinessServiceImpl(GreetingService hiService, GreetingService helloService)
is working fine, since Spring automatically get the names for us.
#3. You can also use Map for this
#Component
#RequiredArgsConstructor
public class BusinessServiceImpl implements BusinessService {
private final Map<String, GreetingService> servicesMap; // Spring automatically get the bean name as key
#Override
public void doGreetings() {
servicesMap.get("hiService").doGreetings();
servicesMap.get("helloService").doGreetings();
}
}
List also works fine if you run all the services. But there is a case that you want to get some specific implementation, you need to define a name for it or something like that. My reference is here
For this one, I use #RequiredArgsConstructor from Lombok.
As mentioned in the comments, by using the #Qualifier annotation, you can distinguish different implementations as described in the docs.
For testing, you can use also do the same. For example:
#RunWith(SpringRunner.class)
#SpringBootTest
public class MyClassTests {
#Autowired
private MyClass testClass;
#MockBean
#Qualifier("default")
private MyImplementation defaultImpl;
#Test
public void givenMultipleImpl_whenAutowiring_thenReturnDefaultImpl() {
// your test here....
}
}
There are 2 approaches when we have autowiring of an interface with multiple implementations:
Spring #Primary annotation
In short it tells to our Spring application whenever we try to autowire our interface to use that specific implementation which is marked with the #Primary annotation. It is like a default autowiring setting. It can be used only once per cluster of implementations of an interface. → #Primary Docs
Spring #Qualifier annotation
This Spring annotation is giving us more control to select the exact implementation wherever we define a reference to our interface choosing among its options. → #Qualifier Docs
For more details follow the links to their documentation.
public interface SomeInterfaces {
void send(String message);
String getType();
}
kafka-service
#Component
public class SomeInterfacesKafkaImpl implements SomeInterfaces {
private final String type = "kafka";
#Override
public void send(String message) {
System.out.println(message + "through Kafka");
}
#Override
public String getType() {
return this.type;
}
}
redis-service
#Component
public class SomeInterfacesRedisImpl implements SomeInterfaces {
private final String type = "redis";
#Override
public void send(String message) {
System.out.println(message + "through Redis");
}
#Override
public String getType() {
return this.type;
}
}
master
#Component
public class SomeInterfacesMaster {
private final Set<SomeInterfaces> someInterfaces;
public SomeInterfacesMaster(Set<SomeInterfaces> someInterfaces) {
this.someInterfaces = someInterfaces;
}
public void sendMaster(String type){
Optional<SomeInterfaces> service =
someInterfaces
.stream()
.filter(service ->
service.getType().equals(type)
)
.findFirst();
SomeInterfaces someService =
service
.orElseThrow(() -> new RuntimeException("There is not such way for sending messages."));
someService .send(" Hello. It is a letter to ....");
}
}
test
#SpringBootTest
public class MultiImplementation {
}
#TestInstance(TestInstance.Lifecycle.PER_CLASS)
class SomeInterfacesMasterTest extends MultiImplementation {
#Autowired
private SomeInterfacesMaster someInterfacesMaster;
#Test
void sendMaster() {
someInterfacesMaster.sendMaster("kafka");
}
}
Thus, according to the Open/Closed principle, we only need to add an implementation without breaking existing code.
#Component
public class SomeInterfacesRabbitImpl implements SomeInterfaces {
private final String type = "rabbit";
#Override
public void send(String message) {
System.out.println(message + "through Rabbit");
}
#Override
public String getType() {
return this.type;
}
}
test-v2
#TestInstance(TestInstance.Lifecycle.PER_CLASS)
class SomeInterfacesMasterTestV2 extends MultiImplementation {
#Autowired
private SomeInterfacesMaster someInterfacesMaster;
#Test
void sendMasterV2() {
someInterfacesMaster.sendMaster("rabbit");
}
}
If we have multiple implementations of the same interface, Spring needs to know which one it should be autowired into a class. Here is a simple example of validator for mobile number and email address of Employee:-
Employee Class:
public class Employee {
private String mobileNumber;
private String emailAddress;
...
/** Getters & Setters omitted **/
}
Interface EmployeeValidator:
public interface EmployeeValidator {
public Employee validate(Employee employee);
}
First implementation class for Mobile Number Validator:
#Component(value="EmployeeMobileValidator")
public class EmployeeMobileValidator implements EmployeeValidator {
#Override
public Employee validate(Employee employee) {
//Mobile number Validation logic goes here.
}
}
Second implementation class for Email address Validator:
#Component(value="EmployeeEmailValidator")
public class EmployeeEmailValidator implements EmployeeValidator {
#Override
public Employee validate(Employee employee) {
//Email address validation logic goes here.
}
}
We can now autowired these above validators individually into a class.
Employee Service Interface:
public interface EmployeeService {
public void handleEmployee(Employee employee);
}
Employee Service Implementation Class
#Service
public class EmployeeServiceImpl implements EmployeeService {
/** Autowire validators individually **/
#Autowired
#Qualifier("EmployeeMobileValidator") // Autowired using qualifier for mobile validator
private EmployeeValidator mobileValidator;
#Autowired
#Qualifier("EmployeeEmailValidator") // Autowired using qualifier for email valodator
private EmployeeValidator emailValidator;
#Override
public void handleEmployee(Employee employee) {
/**You can use just one instance if you need**/
employee = mobileValidator.validate(employee);
}
}
I am using Spring boot and Mockito for testing. I have been able to write test cases for Service layer and they re working fine. But, the test cases for DAO layer do not. The jdbcTemplate object that is mocked and autowired gives null pointer when executing the test case. Below are the details:
My DAOTest class:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = EcommerceApplication.class)
public classEcommerceDaoTest {
#InjectMocks
private IEcommerceDao ecommerceDao = new EcommerceDaoImpl();
#Mock
#Autowired
private JdbcTemplate as400JdbcTemplate;
#Before
public void setUp() throws Exception
{
MockitoAnnotations.initMocks(this);
}
#Test
public void checkOrderExistsTest() throws EcommerceException{
Mockito.when(as400JdbcTemplate.queryForObject(queryForOrder,new Object[]
{"1000"}, int.class)).thenReturn(1);
boolean exists =
ecommerceDao.checkOrderExists("1000");
assertTrue(exists);
}
}
EcommerceDAOImpl.java:
#Override
public boolean checkOrderExists(String orderNo)throws EcommerceException{
boolean doesExist = false;
int count = 0;
try{
count= as400JdbcTemplate.queryForObject(queryForOrder, new Object[]{orderNo}, int.class);
if(count >0){
doesExist = true;
}
}
catch(Exception e){
}
return doesExist;
}
AS400Config.java:
#Bean
#Autowired
public JdbcTemplate as400JdbcTemplate(#Qualifier("as400DataSource")DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
ECommerceApplication.java
#SpringBootApplication(exclude = { DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class })
#EnableTransactionManagement
#Import(As400Configuration.class)
public class EcommerceApplication {
public static void main(String[] args) {
SpringApplication.run(EcommerceApplication.class, args);
}
}
When I am running the test case, I am getting NullPointerException for as400JdbcTemplate. The functionality works fine as is. Its just the test cases for DAO layer that fail because of the inability of the jdbcTemplate to get mocked/autowired.
Please let me know where I am going wrong.
You don't need to use #Mock and #Autowired at the same time. Use only #Mock:
#Mock
private JdbcTemplate as400JdbcTemplate;
Use instead of #RunWith(SpringRunner.class) --> #RunWith(MockitoJUnitRunner.class)
Also to inject mock into DAO you can use ReflectionTestUtils from spring test.
public static void setField(Class targetClass, String name, Object value)
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
ReflectionTestUtils.setField(ecommerceDao ,"as400JdbcTemplate" ,
as400JdbcTemplate);
}
#Mock
private JdbcTemplate as400JdbcTemplate;