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.
question from:
https://stackoverflow.com/questions/31315433/testng-unit-test-not-working-after-annotating-service-to-test-with-retention