gpt4 book ai didi

java - 注释服务以使用@Retention、@Transactional、@Inherited 进行测试后,TestNG 单元测试不起作用

转载 作者:IT老高 更新时间:2023-10-28 20:45:47 32 4
gpt4 key购买 nike

我正在使用 TestNG 测试业务服务,在 Spring Boot 应用程序中进行模拟单元测试。

应用程序是多模块spring boot项目。我正在为业务模块编写单元测试。

我在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>

我的包装注释看起来像

@Service
@Transactional
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyServiceAnnotation{}

我的 TestApp 看起来像

@SpringBootApplication
public class TestApp{ .... }

我的业务服务看起来像

@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 看起来像

@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);
}
}
}

如果我不使用@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Inherited这些注解然后我在测试中的模拟 DAO 调用工作正常。

我需要上面的注释,因为如果我不使用它们,那么,

例如,如果我想执行一个使用多个业务服务的单个任务,那么 它们不会发生在一个事务中。换句话说,如果一个业务调用使用多个业务服务,例如 ServiceAServiceB。调用从 serviceA 转到 serviceB。如果 serviceB 发生异常,则 serviceA 所做的数据库更改不会回滚。

当我使用上面的注释时,上面的例子可以工作,但是在 junit 测试中模拟 DAO 调用不起作用。

我在 pom 中是否有错误的依赖项?

  1. 为什么这不起作用?
  2. 解决办法是什么?

Git Repository Source Code ,在这里你会得到示例代码。它在编译时给了我一些错误。

最佳答案

我建议您保持测试简单。您可以从 DI yield 中获利。更多详情请访问Spring documentation :

One of the major advantages of dependency injection is that it should make your code easier to unit test. You can simply instantiate objects using the new operator without even involving Spring. You can also use mock objects instead of real dependencies.

您的测试类应该如下所示。

public class AddressTest {

@Mock
private UserDAO userDAO;

@Mock
private AddressDAO addressDAO;

@InjectMocks
private AddressService addressServie;

@BeforeMethod
public void initMock() {
addressServie = new AddressServiceImpl();
MockitoAnnotations.initMocks(this);
}

@Test(dataProvider = "getUser", dataProviderClass = UserDP.class)
public void shouldThrowExceptionAddressNotFound(int userId, User user) {
when(userDAO.findOne(userId)).thenReturn(user);
try {
addressServie.findAllAddress(userId);
} catch (BadRequestException badRequestException) {
assertEquals(badRequestException.getErrorCode(), 102);
}
}
}

您还应该在您的实现中检查空地址列表。测试失败,因为提供者类为测试提供了一个未初始化地址列表的用户实例。

@Override
public List<Address> findAllAddress(int userId) {
User user = userDAO.findOne(userId);
if (user == null) {
throw new BadRequestException("Invalid user id", 101);
}
List<Address> addresses = user.getAddresses();
if (addresses == null || addresses.isEmpty()) {
throw new BadRequestException("Address Not found", 102);
}
return addresses;
}

关于java - 注释服务以使用@Retention、@Transactional、@Inherited 进行测试后,TestNG 单元测试不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31315433/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com