【问题标题】:Spy a service spring having transactional methods监视具有事务方法的服务弹簧
【发布时间】:2019-06-28 08:06:46
【问题描述】:

我正在尝试编写一些 JUnit 测试。在我的测试类中,我需要监视一个在实现中具有事务方法的服务。当我试图监视该服务时,我收到此错误:

Mockito cannot mock/spy because :
 - final class

如果我从方法中删除@Transactional,则间谍工作正常。我知道这是因为服务代理的问题。我该如何解决这个问题?

我的测试课:

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

}

【问题讨论】:

    标签: java spring junit service spy


    【解决方案1】:

    根据我发现的this 问题,一种可能的解决方法是使用

    所以不要:spy(proxy) 使用 mock(TestSubject.class, delegatesTo(springProxy))。

    在你的情况下(未经我测试),那可能是

    return Mockito.mock(VirtualControllerService.class, AdditionalAnswers.delegatesTo(virtualControllerService));
    

    请参阅AdditionalAnswers.delegateTo 了解更多信息。请注意,您不能在您的间谍实例中存根或验证内部方法调用(只会跟踪对模拟对象的方法调用)。用例:

    对于难以使用常规间谍 API 进行模拟或监视的对象的间谍或部分模拟很有用。可能的用例:已经自定义的代理对象

    【讨论】:

    【解决方案2】:

    您可以在测试类CreateIfcClusterTaskTest 中使用@Mock 注释来模拟服务实例,而不是在您的配置中创建服务类的bean。

    看起来像这样:

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

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-16
      • 2019-05-17
      • 2018-01-24
      • 1970-01-01
      • 2012-12-24
      • 1970-01-01
      相关资源
      最近更新 更多