I am testing a business service with TestNG, mockito unit tests in spring boot application.
Application is multi-module spring boot project.And I am writing unit tests for business module.
I have added following dependencies related testing in pom,
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<version>${javaxel.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.servlet</artifactId>
<version>${javax.servlet.version}</version>
<scope>test</scope>
</dependency>
My wrapper annotation look like
@Service
@Transactional
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyServiceAnnotation{}
My TestApp looks like
@SpringBootApplication
public class TestApp{ .... }
My Business Service looks like
@MyServiceAnnotation
public class AddressServiceImpl implements AddressService {
@Autowire
UserDAO userDAO;
@Autowire
AddressDAO addressDAO;
public Address find(int userId) {
user = userDAO.findOne(userId);
/** if I run following test then I get user NULL.
But it should get user object which I have created
in data provider
**/
if(user == null ) { throw new BadReqExcp("invalid user Id", 101); }
address = user.findAddresses();
if(address is empty) { throw new BadReqExcp("add not found", 102);}
return address;
}
}
MyTestClass looks like
@ContextConfiguration(classes = { TestApp.class })
class MyTestClass{
@Mock
UserDAO userDAO;
@InjectMocks
@Autowire
AddressService addressServie;
@BeforeMethod
public void initMock() {
MockitoAnnotations.initMocks(this);
}
@Test(dataProvider = "getUser", dataProviderclass = UserDP.class)
public void shouldThrowExceptionAddressNotFound(int userId, User user)
{
when(userDAO.findOne(userId)).thenReturn(user); //here dao call should return user but it is returning null
try{
addressService.find(userId);
}
catch(BadReqExcp e){
// Here errro code should be 102 but fount 101
assertEquals(e.getErrorCode(), 102);
}
}
}
If I don't use @Target(ElementType.TYPE), @Retention(RetentionPolicy.RUNTIME), @Inherited these annotations then my mock DAO calls in test works fine.
I need above annotations explicitly because if I do not use them then,
For example, If I want to perform one single task which uses multiple business service then they wont happen in ONE transaction.
In other words if a business call uses multiple business services say ServiceA and ServiceB. Call goes from serviceA to serviceB. If an exception occurs in serviceB then database changes done by serviceA wont rollback.
When I use above annotations then above example works BUT mock DAO calls in junit tests does not works.
Do I have wrong dependencies in pom?
- Why this is not working ?
- What would be the solution over it ?
Git Repository Source Code , here you will get sample code.It is giving me some error while compiling.