Refit 是一个 REST 库 ,可以根据 annotation 自动生成 HttpClient 请求代码 https://github.com/reactiveui/refit
想从 annotation 中获取请求路径,以便在测试代码中 mock 时重用这个路径,减少重复代码
比如下面的 annotation,想获取 v2/blogposts/public/ids
,请问如何实现?最好借助 refit 已有的实现
public interface IBlogPostClient
{
[Post("v2/blogposts/public/ids")]
Task<int[]> GetPublicPostIds(int[] postIds);
}
参考 Refit 的源码,通过 RestMethodInfo
实现了
var handler = new Mock<HttpMessageHandler>();
var httpClient = handler.CreateClient();
httpClient.BaseAddress = new Uri("http://blog_api");
var apiClientType = typeof(IBlogPostClient);
var restMethod = new RestMethodInfo(
apiClientType,
apiClientType.GetMethods().First(m => m.Name == nameof(IBlogPostClient.GetPublicPostIds)));
handler.SetupRequest(HttpMethod.Post, new Uri(httpClient.BaseAddress, restMethod.RelativePath))
.ReturnsJsonResponse(publicPostIds);
今天发现原来的 RestMethodInfo
被改成了 RestMethodInfoInternal
,无法直接调用了,详见 https://github.com/reactiveui/refit/pull/1496
改为下面更简单的实现
var apiClientType = typeof(IBlogPostClient);
var methodName = nameof(IBlogPostClient.GetPublicPostIds);
var hma = apiClientType.GetMethods().First(m => m.Name == methodName)
.GetCustomAttributes(true)
.OfType<HttpMethodAttribute>()
.First();
var requestUri = new Uri(_baseAddress, hma.Path);
_mockHandler.SetupRequest(HttpMethod.Post, requestUri)
.ReturnsJsonResponse(publicPostIds);
1、后端 web api 路由中 必须的
2、api 客户端 HttpClient 中 refit不是有resetclient么, 用它自己的, 不直接用httpclient就可以了呀
3、测试代码的 mock 中 简单的写个扩展方法?, 大概看看 RequestBuilder.For..... 之类的方法出来的东西有没有能用的?
2、[Post("v2/blogposts/public/ids")]
就是为 refit 而写,这就是第2遍
3、mock 中的第3次可以看 https://q.cnblogs.com/q/142495/