基于MockWebServer的Springboot WebClient单元测试



在网上搜索了几天后,我真的找不到我用例所需的资源,因为其中许多都是用Java实现的。

我有一个调用外部api的服务类,我正试图用MockWebServer在其上编写单元测试

@Service
class ApiService {
@Autowired
private lateinit var webClient: WebClient
fun getApiResult(name: String): ResultDto? {
return try {
webClient
.get()
.uri("https://www.example.com/")
.retrieve()
.bodyToMono(Result::class)
.block()
catch {
null
}
}
}
@ExtendWith(MockitoExtension::class)
@MockitoSettings(strictname = Strictness.LENIENT)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class ApiServiceTest {
@Mock
private lateinit var webClient: WebClient
@InjectMocks
private lateinit var mockApiService: ApiService
private val mockName = "mockName"
private val mockDetailDto = DetailDto(name = "mockName", age = 18)
@Test
fun canGetDetails() {
mockWebServer.enqueue(
MockResponse()
.setResponse(200)
.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.setBody(mockDetailDto))
)
mockApiService.getApiResult(mockName)
val request: RecordedRequest = mockWebServer.takeRequest()
// Assert statements with request
}
}

然而,我得到了lateinit property webClient has not been initialised。但是,如果我在测试中使用@Spy而不是@Mock用于webClient,它将进行实际的api调用,这不是单元测试的目标。我的目标是能够检查request中的一些细节,例如GET及其返回值。感谢社区的帮助。

根据我的意见,您不需要添加一些配置,为了自动解决它,您可以尝试为此进行集成测试。这样的

@WithMockUser//if you use spring secutity
@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = RANDOM_PORT)
class MyTest {
@Autowired
private MockMvc mvc;
}
并为快速加载环境做一个测试应用程序
@SpringBootApplication
@ConfigurationPropertiesScan
@ComponentScan(lazyInit = true)//make loading is faster
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}

这种方式可以像prod模式一样加载完整的上下文配置,当然只有在使用lazyInit = true

时才适用于被调用的方法

最新更新