侦测具有事务方法的服务 spring
Spy a service spring having transactional methods
我正在尝试编写一些 JUnit 测试。在我的测试中 class 我需要监视一个在实现中具有事务方法的服务。当我试图监视该服务时,出现此错误:
Mockito cannot mock/spy because :
- final class
如果我从方法中删除 @Transactional
,则间谍工作正常。我知道这是因为服务代理的问题。我该如何解决这个问题?
我的测试class:
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {CreateIfcClusterTaskTest.Config.class})
@DirtiesContext(classMode =
DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class CreateIfcClusterTaskTest {
static class Config extends SpringTestConfiguration {
@Bean
@Primary
public VirtualControllerService
virtualControllerService(VirtualControllerService
virtualControllerService) {
return Mockito.spy(virtualControllerService);
}
}
}
我的服务 - VirtualControllerService
:
public interface VirtualControllerService {
JsonHost createVifcHostForWebApi(VirtualController virtualController);
void stopDocker(DockerClient docker, String joinerIpAddress) throws
DockerException, InterruptedException;
}
我的服务实现 - VirtualControllerServiceImpl
:
@Service
public class VirtualControllerServiceImpl implements
VirtualControllerService {
@Override
@Transactional
public JsonHost createVifcHostForWebApi(VirtualController
virtualController) {
JsonHost jsonHost = new JsonHost();
jsonHost.setIP(virtualController.getIpAddress());
jsonHost.setUser(environment.getProperty("VIFC_WEBAPI_USER"));
jsonHost.setPassword(environment.getProperty("VIFC_WEBAPI_PASSWORD"));
return jsonHost;
}
}
无需在配置中创建服务 bean class,您可以在测试 Class CreateIfcClusterTaskTest
中使用 @Mock 注释来模拟服务实例。
看起来像这样:
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = { CreateIfcClusterTaskTest.Config.class })
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class CreateIfcClusterTaskTest {
@Mock
VirtualControllerService virtualControllerService;
}
并且您必须使用 Mockito 的注释初始化对象,如下所示:
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
希望对您有所帮助。
根据我发现的 this 问题,一种可能的解决方法是使用
So instead of : spy(proxy) use mock(TestSubject.class, delegatesTo(springProxy)).
在你的情况下(未经我测试),那可能是
return Mockito.mock(VirtualControllerService.class, AdditionalAnswers.delegatesTo(virtualControllerService));
有关详细信息,请参阅 AdditionalAnswers.delegateTo
。请注意,您无法在您的间谍实例中对内部方法调用进行存根或验证(只会跟踪对模拟对象的方法调用)。用例:
Useful for spies or partial mocks of objects that are difficult to mock or spy using the usual spy API. Possible use cases: Already custom proxied object
我正在尝试编写一些 JUnit 测试。在我的测试中 class 我需要监视一个在实现中具有事务方法的服务。当我试图监视该服务时,出现此错误:
Mockito cannot mock/spy because :
- final class
如果我从方法中删除 @Transactional
,则间谍工作正常。我知道这是因为服务代理的问题。我该如何解决这个问题?
我的测试class:
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {CreateIfcClusterTaskTest.Config.class})
@DirtiesContext(classMode =
DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class CreateIfcClusterTaskTest {
static class Config extends SpringTestConfiguration {
@Bean
@Primary
public VirtualControllerService
virtualControllerService(VirtualControllerService
virtualControllerService) {
return Mockito.spy(virtualControllerService);
}
}
}
我的服务 - VirtualControllerService
:
public interface VirtualControllerService {
JsonHost createVifcHostForWebApi(VirtualController virtualController);
void stopDocker(DockerClient docker, String joinerIpAddress) throws
DockerException, InterruptedException;
}
我的服务实现 - VirtualControllerServiceImpl
:
@Service
public class VirtualControllerServiceImpl implements
VirtualControllerService {
@Override
@Transactional
public JsonHost createVifcHostForWebApi(VirtualController
virtualController) {
JsonHost jsonHost = new JsonHost();
jsonHost.setIP(virtualController.getIpAddress());
jsonHost.setUser(environment.getProperty("VIFC_WEBAPI_USER"));
jsonHost.setPassword(environment.getProperty("VIFC_WEBAPI_PASSWORD"));
return jsonHost;
}
}
无需在配置中创建服务 bean class,您可以在测试 Class CreateIfcClusterTaskTest
中使用 @Mock 注释来模拟服务实例。
看起来像这样:
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = { CreateIfcClusterTaskTest.Config.class })
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class CreateIfcClusterTaskTest {
@Mock
VirtualControllerService virtualControllerService;
}
并且您必须使用 Mockito 的注释初始化对象,如下所示:
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
希望对您有所帮助。
根据我发现的 this 问题,一种可能的解决方法是使用
So instead of : spy(proxy) use mock(TestSubject.class, delegatesTo(springProxy)).
在你的情况下(未经我测试),那可能是
return Mockito.mock(VirtualControllerService.class, AdditionalAnswers.delegatesTo(virtualControllerService));
有关详细信息,请参阅 AdditionalAnswers.delegateTo
。请注意,您无法在您的间谍实例中对内部方法调用进行存根或验证(只会跟踪对模拟对象的方法调用)。用例:
Useful for spies or partial mocks of objects that are difficult to mock or spy using the usual spy API. Possible use cases: Already custom proxied object