使用Mock运行单元测试报错:when()参数需为Mock对象方法调用
解决Mockito报错:
when() requires an argument which has to be 'a method call on a mock' 问题根源
你用@Mock注解声明了apiClientUtilsMock作为Mock对象,但在setup()方法里又执行了apiClientUtilsMock = new ApiClientUtils(new ApiClientTimeoutConfiguration());——这行代码直接把Mockito生成的Mock对象覆盖成了真实的ApiClientUtils实例。后续调用when(apiClientUtilsMock.createClientCredentialsResourceDetails(...))时,操作的是真实对象而非Mock对象,因此触发报错。
修复步骤
直接删除setup()方法中创建真实ApiClientUtils实例的代码行:
apiClientUtilsMock = new ApiClientUtils(new ApiClientTimeoutConfiguration());
Mockito会通过@Mock注解自动生成并注入Mock实例,无需手动创建真实对象。
修复后的完整测试类代码
@ExtendWith(MockitoExtension.class) class CustomerDaoConfigurationTest { private CustomerDaoConfiguration customerDaoConfiguration; private CustomerApiProperties properties; @Mock private ApiClientUtils apiClientUtilsMock; @Mock // 单元测试无需@MockBean,换成@Mock即可 private ApiClientTimeoutConfiguration apiClientTimeoutConfiguration; @BeforeEach void setup() { properties = new CustomerApiProperties(); properties.setBaseUrl("MockBaseUrl"); properties.setOauth(new OAuthProperties("token-url", "client-id", "client-secret")); customerDaoConfiguration = new CustomerDaoConfiguration(properties, apiClientUtilsMock, apiClientTimeoutConfiguration); } @Test void shouldCreateValidRestTemplateWhenPropertiesAreProvided() { ClientCredentialsResourceDetails clientCredentialsResourceDetails = new ClientCredentialsResourceDetails(); clientCredentialsResourceDetails.setClientSecret("client-secret"); clientCredentialsResourceDetails.setClientId("client-id"); clientCredentialsResourceDetails.setTokenName("token-name"); clientCredentialsResourceDetails.setAccessTokenUri("token-url"); OAuthProperties oauth = properties.getOauth(); List<HttpMessageConverter<?>> messageConverters = new ArrayList<>(); messageConverters.add(new JsonApiHttpMessageConverter(new ResourceConverter(), new ObjectMapper())); when(apiClientUtilsMock.createClientCredentialsResourceDetails(oauth)).thenReturn(clientCredentialsResourceDetails); RestTemplate createdRestTemplate = customerDaoConfiguration.customerRestTemplate(new SimpleClientHttpRequestFactory(), messageConverters); assertThat(createdRestTemplate.getMessageConverters().size(), is(1)); HttpMessageConverter<?> messageConverter = createdRestTemplate.getMessageConverters().get(0); assertThat(messageConverter, is(instanceOf(JsonApiHttpMessageConverter.class))); } }
额外说明
@MockBean是Spring Boot集成测试专用注解,用于向Spring容器注入Mock对象;纯单元测试场景下,用@Mock配合MockitoExtension即可完成Mock对象的创建。- 这是Mockito使用的常见坑点:如果用注解声明了Mock对象,切勿再手动创建真实实例覆盖它,否则Mockito无法拦截方法调用进行Mock配置。
内容的提问来源于stack exchange,提问作者ljs
相关产品推荐
相关产品推荐

