我正在测试“保存在数据库中”公共方法,该方法还将一些已修改的已保存数据发送到服务。该测试确保它保存了收到的内容,但发送的修改后的数据有所不同。当内部私有方法调用设置为自动装配的存储库时,就会出现问题,因为反映为未初始化自动装配的存储库。
所以首先要断言私有方法的答案是我对私有方法的反思。我用受控的响应模拟了内部自动装配服务,但没有发现如何在我的私有反射上设置模拟服务的答案。
我还是测试的新手,所以我可能会犯一些错误,以便解释会尽力纠正它,并进一步扩展该主题。
这是针对公共方法“ X”的,该方法将某些内容保存在数据库中(返回所保存内容的代码),然后执行其他操作,然后转到私有方法“ Y”以验证一些数据并在该私有方法内转到其他私有方法“ Z”,以创建一些新数据,以从另一个服务“ B”中检索数据并将其从之前的数据中获取,然后将其发送到外部服务“ A”。所有这些都是在同一类实现“ classImpl”中完成的。私有方法“ Z”的接收方式与“ X”方法相同,它使用从“ B”获得的数据生成并返回要在“ A”服务中发送的数据。
@Test
@Rollback(false)
@Transactional(readOnly = false)
TEST{
testData testXData= new testData();
testXData.set()...
testXData.set()...
.......Generate data to be saved.
mockResponse controlledOutput = mock(mockResponse.class);
deliverInMockResponse deliverInMockResponse = new deliverInMockResponse();
deliverInMockResponse.set()...
deliverInMockResponse.set()...
.......Generate data to be delivered in the mockResponse.
when(controlledOutput.findByAnd(otherSomething)).thenReturn(deliverInMockResponse);
assertNotNull(testSaveMethodX(testXData));
String Something = "evalutaThis";
assertEquals(testXData.getSomething(),Something);
try{
classImpl publicImpl = new classImpl();
Method method = classImpl.class.getDeclaredMethod("Z", testData.class);
method.setAccessible(true);
methodZResponse Zoutput = (methodZResponse) method.invoke(publicImpl, testXData);
assertNotEquals(Zoutput.getSomething(),Something);
}
catch (Exception e){
assertNotNull(null);
}
}
答案 0 :(得分:0)
对于私有方法的模拟或测试,我建议您尝试PowerMock而不是自己写反射。 here是一个很好的指南。另外Mock private method using PowerMockito
答案 1 :(得分:0)
如果您在测试中运行自己制作的反射代码,那么可能更好地完成了测试代码。
并非所有代码都可以自动进行单元测试。为了能够测试代码,您应该以某种方式编写代码。
您已经在一个问题的代码段中显示了该测试,但是您在此测试的代码也非常重要。 从问题的第一段开始,我假设您有以下内容:
Future[Map[A, Seq[B]]]
由于在测试过程中不会发生自动装配(因为在单元测试中您没有让Spring发挥作用的能力),所以您很难测试class MyDao {
@Autowired
private SomeService service;
public void saveInDb() {
// do something with db
service.sendData();
}
}
方法
但是,此代码有问题,可以重构以进行更好的单元测试:
因此,这里有个提示:不要在字段上使用自动装配,而是使用构造函数注入重写代码:
saveInDb
如果您觉得这是很多代码,甚至可以使用Lombok项目为您生成一个构造函数,但这超出了问题的范围...
一种或另一种方式是,您现在拥有一个类,该类具有定义明确的依赖项列表,必须在尝试创建此类实例的测试中指定必须。
在这里单元测试变得容易
class MyDao {
private SomeService service;
@Autowired // you can even omit this annotation in recent versions of spring
// spring will understand what should be injected if there is only one
// constructor in the class
public MyDao(SomeService service) {
this.service = service;
}
}
与袁庆飞给出的先前答案不同,我不建议使用PowerMock / PowerMockito之类的工具,仅在无法更改测试代码的情况下才考虑使用这些工具(通常对于未经测试而编写的旧项目而言,这是正确的)介意)