Mockito:如何在春豆中部分模拟字段依赖



我有一个具有多个字段依赖项的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 注入其他依赖项?

您可以使用 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 注释。

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

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

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

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

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

确保您:

1(@Before方法中启动模拟

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

2(@RunWith类注解中使用SpringJUnit4ClassRunner.class

最新更新