我有一个带有公开方法的服务,该方法带有标记为org.springframework.transaction.annotation.Transactional
的数据库操作。
我想通过Java反射访问service.getClass().getDeclaredMethod('privateMethod', args)
的私有方法(无事务注释)。
当我调用它时,我获取了java.lang.NoSuchMethodException
。当我删除所有带有@Transactional
注释的方法时,它可以工作。有这种行为有什么原因,我该如何解决?
public class MyService {
@Transactional(readOnly = true)
public Integer publicMethodMarkedWithTransactional(int a, int b) {
//couple of database requests
return privateMethod(b, a);
}
private Integer privateMethod(int a, int b) {
return a + b;
}
}
public class MyServiceTest {
@Autowired
private MyService service;
@Test
public void test() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Method privateMethod = service.getClass().getDeclaredMethod("privateMethod", int.class, int.class);
privateMethod.setAccessible(true);
int res = (int) privateMethod.invoke(service, 5, 10);
assertEquals(5 + 10, res);
}
}
答案 0 :(得分:3)
您可以导入ReflectionUtils
:
import { timeout } from 'rxjs/operators';
...
this.contratService.update(lineSelected.id)
.pipe(
timeout(30000)
)
.subscribe(response => {
if (response.status === 201) {
....
}
}, error => {
console.log('Error in contrat update');
});
测试将如下所示:
import org.springframework.data.util.ReflectionUtils;
但是,我建议不要以这种方式编写测试-您应该找到一种测试API的方式。私有方法不是API的一部分,以这种方式进行测试会使您的测试更加脆弱。
答案 1 :(得分:2)
是的,这是有原因的:事务处理基于代理。您正在尝试在事务代理上调用私有方法。
代理仅实现服务的公共方法,因为您不应使用反射并调用私有方法。由于某种原因,它们是私人的。
如果您需要从该服务之外调用服务的方法,请将其公开。