繁体   English   中英

Mockito:如何在Spring Bean中部分模拟字段依赖项

[英]Mockito: How to mock field dependencies partially in spring bean

我有一个具有多个字段依赖项的Spring服务,如下所示。 依赖项之一( thirdPartyService )与外部应用程序通信。 我怎么能嘲笑呢?

@Service
public class PlannerServiceImpl implements PlannerService {
    private static final Logger LOG = LoggerFactory.getLogger(PlannerServiceImpl.class);

    @Autowired
    private RepositoryA repositoryA;

    @Autowired
    private RepositoryB repositoryB;

    @Autowired
    private ThirdPartyService thirdPartyService ;

}

如果我使用Mock注释,那么它仍然会连接到外部应用程序,而不是返回模拟响应:

@Mock
ThirdPartyService thirdPartyService;

@Autowired
PlannerService plannerService;

而且,如果我使用InjectMocks批注,则它将为RepositoryARepositoryB提供NullpointerException

@Mock
ThirdPartyService thirdPartyService;

@InjectMocks 
PlannerService plannerService = newPlannerService();

我如何只模拟ThirdPartyService并让Spring注入其他依赖项?

您可以在受测的PlannerService类中使用setter方法

void  setRepositoryA(RepositoryA repository) {
    this.repositoryA = repository;
}

然后在测试中使用此方法来提供RepositoryA的模拟实现

或者,您可以@Inject在构造函数中注入存储库,然后在单元测试中使用模拟作为参数调用构造函数。

您可以使用Whitebox修改Spring注入的内容。 (可选)由于使用的是Spring,因此也可以使用ReflectionTestUtils.setField

在Spring注入依赖项之后,以及在单元测试运行之前,您可以使用org.powermock.reflect.Whitebox修改Spring的注入。 像这样

Whitebox.setInternalState(plannerService, "thirdPartyService" thirdPartyService);

其中thirdPartyService是您的模拟实例。

这里的javadoc

或使用Spring的ReflectionTestUtils

ReflectionTestUtils.setField((plannerService, "thirdPartyService" thirdPartyService);

Java文档在这里

这通常可以在您的“设置”方法中完成,该方法使用@Before注释。

可以肯定在测试用例中使用@Autowiring@InejctMocks (在不同的实例字段上分别使用注释)。

确保你:

1)@Before方法中启动Mockito @Before

@Before
public void before(){
 MockitoAnnotations.initMocks(this);
}

2)@RunWith类注释中使用SpringJUnit4ClassRunner.class

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM