日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

你可能会用到的 Mock 小技巧

發(fā)布時(shí)間:2023/12/4 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 你可能会用到的 Mock 小技巧 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

你可能會(huì)用到的 Mock 小技巧

Intro

最近看到阿迪分享了兩篇 Mock 相關(guān)的文章,于是想把自己遇到的一些可能對(duì)你有幫助的一些小技巧分享一下,大概總結(jié)了一下,且看下文

AsyncEnumerable

在 C# 8 中引入了異步流,AsyncEnumerable,在有些類庫(kù)中已經(jīng)引入了這一語(yǔ)法,在 StackExchange.Redis 中 HashScanAsync 的返回值就是 IAsyncEnumerable<HashEntry>

使用示例如下:

var?dic?=?new?Dictionary<string,?string>(); await?foreach?(var?entry?in?db.HashScanAsync(setName,?"*")) {dic[entry.Name]?=?entry.Value; }

在 Mock 的時(shí)候,我們可以通過(guò)下面的 MockAsyncEnumerable 比較方便的指定一個(gè) IEnumerable 對(duì)象來(lái)實(shí)現(xiàn)一個(gè) IAsyncEnumerable 對(duì)象

private?class?MockAsyncEnumerable<T>?:?IAsyncEnumerable<T> {private?readonly?IEnumerable<T>?_data;public?MockAsyncEnumerable(IEnumerable<T>?data){_data?=?data;}public?IAsyncEnumerator<T>?GetAsyncEnumerator(CancellationToken?cancellationToken?=?new?CancellationToken()){return?new?MockAsyncEnumerator<T>(_data.GetEnumerator());} }private?class?MockAsyncEnumerator<T>?:?IAsyncEnumerator<T> {private?readonly?IEnumerator<T>?_enumerator;public?MockAsyncEnumerator(IEnumerator<T>?enumerator){_enumerator?=?enumerator;}public?ValueTask?DisposeAsync(){_enumerator.Dispose();return?default;}public?ValueTask<bool>?MoveNextAsync(){return?new?ValueTask<bool>(_enumerator.MoveNext());}public?T?Current?=>?_enumerator.Current; }

使用示例如下:

var?entries?=?new?HashEntry[10]; databaseMock.Setup(c?=>?c.HashScanAsync(setName,?"*",?200,?0,?0,?CommandFlags.None)).Returns(new?MockAsyncEnumerable<HashEntry>(entries));

HttpClient Mock

一個(gè)項(xiàng)目中經(jīng)常會(huì)遇到調(diào)用第三方的 API,如何比較方便的 Mock 一個(gè) HttpClient 的行為呢,我們可以通過(guò)自定義一個(gè) HttpHandler 來(lái)實(shí)現(xiàn)自定義響應(yīng)信息,通常我們需要根據(jù)不同的請(qǐng)求信息返回不同的響應(yīng),我們自定義了一個(gè) MockHttpHandler 來(lái)實(shí)現(xiàn)比較方便的 Mock 第三方 API 的行為,實(shí)現(xiàn)如下:

internal?class?MockHttpHandler?:?DelegatingHandler {private?readonly?Func<HttpRequestMessage,?HttpResponseMessage>?_getResponseFunc;public?MockHttpHandler(Func<HttpRequestMessage,?HttpResponseMessage>?getResponseFunc){_getResponseFunc?=?getResponseFunc;}protected?override?Task<HttpResponseMessage>?SendAsync(HttpRequestMessage?request,?CancellationToken?cancellationToken){return?Task.FromResult(_getResponseFunc(request));} }

使用示例如下:

using?var?client?=new?HttpClient(new?MockHttpHandler(req?=>?new?HttpResponseMessage(HttpStatusCode.BadRequest))){BaseAddress?=?new?Uri("https://api.weihanli.xyz/")}; // using?var?httpClient?=?new?HttpClient(new?MockHttpHandler(request?=> {var?statusCode?=?request.RequestUri.AbsoluteUri.Contains("templateId=1")???HttpStatusCode.NotFound?:?(request.RequestUri.AbsoluteUri.Contains("templateId=2")???HttpStatusCode.BadRequest?:?HttpStatusCode.InternalServerError);return?new?HttpResponseMessage(statusCode){Content?=?new?StringContent(JsonConvert.SerializeObject(new{Code?=?statusCode.ToString(),Msg?=?"The?template?not?exists"}))}; }))

MVC HttpContext Mock

HttpContext mock 示例:

var?services?=?new?ServiceCollection().AddScoped<CurrentUser>(sp?=>?new?CurrentUser(){UserID?=?1,UserName?=?"admin"}).BuildServiceProvider();var?mock?=?new?Mock<HttpContext>(); //?Mock?HttpContext.User mock.SetupGet(x?=>?x.User).Returns(new?ClaimsPrincipal(new?ClaimsIdentity(new?Claim[]{new?Claim(ClaimTypes.Name,?"admin"),new?Claim(ClaimTypes.Email,?"weihan.li@iherb.com"),},?JwtBearerDefaults.AuthenticationScheme))); //?Mock?RequestServices mock.Setup(x?=>?x.RequestServices).Returns(services);var?controller?=?new?CommonController(NullLogger<CommonController>.Instance) {ControllerContext?=?new?ControllerContext()?{HttpContext?=?mock.Object?} };

MVC ExceptionFilter test

有時(shí)我們會(huì)在項(xiàng)目里使用到 ExceptionFilter 來(lái)捕獲 MVC 中未捕獲的異常,如果想要針對(duì)自定義的 ExceptionFilter 寫一些測(cè)試用例可以參考下面的測(cè)試用例:

[Fact] public?async?Task?ExceptionTest() {var?filters?=?new?IFilterMetadata[]{new?ResultExceptionFilter()};var?exceptionContext?=?new?ExceptionContext(new?ActionContext(){HttpContext?=?new?DefaultHttpContext(){RequestServices?=?new?ServiceCollection().AddLogging().BuildServiceProvider()},RouteData?=?new?RouteData(new?RouteValueDictionary(){{"controller",?"Test"},{"action",?"Test"},}),ActionDescriptor?=?new?ActionDescriptor(),},?filters){Exception?=?new?NotImplementedException()};var?invoker?=?new?Mock<IActionInvoker>();invoker.Setup(x?=>?x.InvokeAsync()).Callback(()?=>{new?ResultExceptionFilter().OnException(exceptionContext);}).Returns(Task.CompletedTask);await?invoker.Object.InvokeAsync();//?... }

Mock Data

字符串

在我們的代碼中經(jīng)常會(huì)出現(xiàn)對(duì)輸入?yún)?shù)進(jìn)行校驗(yàn)是否為空,對(duì)于這樣的數(shù)據(jù)每次都取寫一遍就會(huì)有點(diǎn)煩,所以寫了一個(gè)自定義測(cè)試數(shù)據(jù),就是返回 null/空字符串,實(shí)現(xiàn)代碼如下:

public?class?NullOrEmptyStringDataAttribute?:?DataAttribute {public?bool?IncludeWhitespace?{?get;?set;?}public?override?IEnumerable<object[]>?GetData(MethodInfo?testMethod){yield?return?new?object[]?{?null?};yield?return?new?object[]?{?string.Empty?};if?(IncludeWhitespace){yield?return?new?object[]?{?"?"?};}} }

使用示例如下:

[Theory] [NullOrEmptyStringData] public?void?Test(string?name) {Assert.True(string.IsNullOrEmpty(name)); }[Theory] [NullOrEmptyStringData(IncludeWhitespace=true)] public?void?Test1(string?name) {Assert.True(string.IsNullOrWhitespace(name)); }

Number

對(duì)于 id 之類的數(shù)據(jù),通過(guò)我們需要檢查是否大于0,在寫測(cè)試的時(shí)候需要考慮小于等于 0 的情況,通常我們也可以像上面那樣做一個(gè)簡(jiǎn)單的封裝,實(shí)現(xiàn)代碼如下:

public?class?LessThanOrEqualDataAttribute?:?DataAttribute {public?int?Value?{?get;?set;?}public?override?IEnumerable<object[]>?GetData(MethodInfo?testMethod){yield?return?new?object[]?{?Value?};yield?return?new?object[]?{?Value?-?1?};} }

使用實(shí)例如下:

[Theory] [LessThanOrEqualData] public?async?Task?GetCategoryIdInfo_BadRequest(int?id) {var?result?=?await?_controller.GetCategoryIdInfo(id,?null);result.AssertCode(ErrorCode.BadRequest); }

More

上面是一些我寫測(cè)試用例的時(shí)候可能會(huì)用到的一些幫助類或 Mock 方法,希望能對(duì)你有所幫助~

你在寫測(cè)試用例的過(guò)程中還有哪些覺(jué)得比較實(shí)用或者有哪些測(cè)試用例覺(jué)得比較難寫呢?

總結(jié)

以上是生活随笔為你收集整理的你可能会用到的 Mock 小技巧的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。