手把手教你如何进行 Golang 单元测试:详细步骤与最佳实践

2024-12-12 0 183

package unit
import (
 "encoding/json"
 "errors"
 "github.com/gomodule/redigo/redis"
 "regexp"
)
type PersonDetail struct {
 Username string `json:"username"`
 Email    string `json:"email"`
}
// 检查用户名是否非法
func checkUsername(username string) bool {
 const pattern = `^[a-z0-9_-]{3,16}​手把手教你如何进行 Golang <a href='https://www.7claw.com/2801024.html' title='单元测试' target='_blank' rel="noopener">单元测试</a> - 今日头条{"@context":"https://schema.org","@type":"NewsArticle","mainEntityOfPage":{"@type":"WebPage","@id":"https://www.toutiao.com/article/7194623951715303970/"},"headline":"​手把手教你如何进行 Golang 单元测试","description":"引入随着工程化开发的内大力的推广,单元测试越来越受到广大开发者的重视。在学习的过程中,发现网上针对 Golang 单元测试大多从理论角度出发介绍,缺乏完整的实例说明,晦涩难懂的 API 让初学接触者难以下手。","image":["https://www.7claw.com/wp-content/uploads/2024/12/1734005244579_0.jpg","https://p3-sign.toutiaoimg.com/tos-cn-i-qvj2lq49k0/2f1220bbf1064c8a9eb83d7188697332~tplv-tt-origin-web:gif.jpeg?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1734609857&x-signature=6LvsZwDUwu%2BW76ZO0A0u9onC%2BDQ%3D","https://p3-sign.toutiaoimg.com/tos-cn-i-qvj2lq49k0/4f76255f3b074051aac9d049e5fe72ea~tplv-tt-origin-web:gif.jpeg?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1734609857&x-signature=HmsxOGVN213kq4mh2c3SQZOiCLQ%3D"],"datePublished":"2023-01-31T10:22:32+08:00","dateModified":"2024-11-23T01:11:32+08:00","author":{"@type":"Person","name":"Freemen程序员招聘app","url":"https://www.toutiao.com/c/user/token/MS4wLjABAAAAJOciZkc9eBL9yaD0sqJ6EvcVuBksXQMzilpmr2mk6bGNzfFMOA1wkQR9ctLoqvqA/"},"publisher":{"@type":"Organization","name":"今日头条","url":"https://www.toutiao.com/","logo":{"@type":"ImageObject","url":"https://lf3-static.bytednsdoc.com/obj/eden-cn/uhbfnupkbps/216.png"}}}!function(r,e,t,n,s,a,o,i,c,l,d,p,m,f){a="precollect",o="getAttribute",i="addEventListener",(l=function(e){(d=[].slice.call(arguments)).push(Date.now(),location.href),(e==a?l.p.a:l.q).push(d)}).q=[],l.p={a:[]},r[s]=l,(p=document.createElement("script")).src=t+"?bid=toutiao_web_pc&globalName="+s,p.crossOrigin=0<t.indexOf("sdk-web")?"anonymous":"use-credentials",e.getElementsByTagName("head")[0].appendChild(p),i in r&&(l.pcErr=function(e){e=e||r.event,(m=e.target||e.srcElement)instanceof Element||m instanceof HTMLElement?m[o]("integrity")?r[s](a,"sri",m[o]("href")||m[o]("src")):r[s](a,"st",{tagName:m.tagName,url:m[o]("href")||m[o]("src")}):r[s](a,"err",e.error||e.message)},l.pcRej=function(e){e=e||r.event,r[s](a,"err",e.reason||e.detail&&e.detail.reason)},r[i]("error",l.pcErr,!0),r[i]("unhandledrejection",l.pcRej,!0)),"PerformanceLongTaskTiming"in r&&((f=l.pp={entries:[]}).observer=new PerformanceObserver(function(e){f.entries=f.entries.concat(e.getEntries())}),f.observer.observe({entryTypes:["longtask","largest-contentful-paint","layout-shift"]}))}(window,document,"https://lf3-short.ibytedapm.com/slardar/fe/sdk-web/browser.cn.js",0,"Slardar")window.Slardar&&window.Slardar("init",{bid:"toutiao_web_pc",pid:"news_article_detail",release:"1.0.0.2328",env:"online",sample:{sample_rate:1},plugins:{ajax:{ignoreUrls:["mcs.snssdk.com","mcs.zijieapi.com","i.snssdk.com","verify.snssdk.com","vcs.snssdk.com","mon.zijieapi.com","mon.snssdk.com"]},pageview:{routeMode:"manual"},blankScreen:{rootSelector:"#root"}}})!function(n,t){if(n.LogAnalyticsObject=t,!n[t]){function c(){c.q.push(arguments)}c.q=c.q||[],n[t]=c}n[t].l=+new Date}(window,"collectEvent")window.collectEvent("usePlugin","autotrack"),window.collectEvent("usePlugin","stay"),window.collectEvent("init",{app_id:24,channel:"cn",autotrack:{custom:"tea",text:!0},enable_stay_duration:!0}),window.collectEvent("config",{evtParams:{url:window.location.href,screen_width:window.screen.width,screen_height:window.screen.height,screen_inner_width:window.innerWidth,screen_inner_height:window.innerHeight}})window.byted_acrawler&&window.byted_acrawler.init({aid:24,dfp:!0})!function(){var a="24",r="6457";var n=function(e,t,n){if(Math.ceil(100*Math.random())<=100*t){var o={ev_type:"batch",list:[{ev_type:"custom",payload:{name:"sdk_glue_load",type:"event",metrics:{},categories:{sdk_glue_load_status:e,sdk_glue_load_err_src:n,payload_bdms_aid:a,payload_bdms_page_id:r}},common:{context:{ctx_bdms_aid:a,ctx_bdms_page_id:r},bid:"web_bdms_cn",pid:window.location.pathname,view_id:"/_1",user_id:"",session_id:"0-a-1-2-c",release:"",env:"production",url:window.location.href,timestamp:+new Date,sdk_version:"1.6.1",sdk_name:"SDK_SLARDAR_WEB"}}]},i=new XMLHttpRequest;i.open("POST","https://mon.zijieapi.com/monitor_browser/collect/batch/?biz_id=web_bdms_cn",!0),i.setRequestHeader("Content-type","application/json"),i.send(JSON.stringify(o))}};!function(){try{(function(){try{var e="gfkadpd",t="24,"+r,n=function(e){for(var t=document.cookie.split(";"),n=0;n<t.length;n++){var o=t[n].trim();if(o.startsWith(e+"="))return o.substring(e.length+1)}return null}(e);if(n){if(-1!=n.indexOf(t))return;t+="|"+n}document.cookie=e+"="+t+"; expires="+new Date((new Date).getTime()+2592e5).toUTCString()+"; path=/; SameSite=None; Secure;"}catch(e){}})(),document.cookie="wdglgl=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/;",n("before_load",.1,"")}catch(e){}window.addEventListener("error",function(e){try{var t=e.target||e.srcElement;t instanceof HTMLElement&&"SCRIPT"==t.nodeName&&-1!=(t.src||"").indexOf("sdk-glue")&&(document.cookie="wdglgl=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/;",document.cookie="wdglgl="+(new Date).getTime()+"; expires="+new Date((new Date).getTime()+2592e5).toUTCString()+"; path=/; SameSite=None; Secure;",n("load_error",1,t.src))}catch(e){}},!0)}()}()window._SdkGlueInit&&window._SdkGlueInit({self:{aid:24,pageId:6457},bdms:{aid:24,pageId:6457,paths:["/api/pc/list/feed","/api/pc/list/user/feed"]}})window.TTGCaptcha&&window.TTGCaptcha.init({commonOptions:{aid:24,iid:"0",did:"0"}})window.secsdk&&window.secsdk.csrf.setProtectedHost({"www.toutiao.com":{GET:[],POST:[/^/api/pc/user/fans_digg/,/^/api/pc/user/delete/,/^/api/pc/user/follow/,/^/c/ugc/content/repost/,/^/group/repin/,/^/group/unrepin/,/^/api/pc/user/stick/,/^/api/pc/user/unstick/,/^/c/user/unfollow/,/^/wenda/v5/interact/followanswer/,/^/wenda/v5/interact/followquestion/,/^/wenda/v5/interact/digganswer/,/^/wenda/v5/interact/deleteanswer/,/^/user_data/batch_action/,/^/action/api/v1/do_action/],PUT:[],PATCH:[],DELETE:[]}})"undefined"!=typeof window&&"serviceWorker"in navigator&&window.addEventListener("load",function(){navigator.serviceWorker.register("/sw.js").catch(function(e){window.Slardar&&window.Slardar("emit","counter",{name:"sw-register-error",value:1})})})function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-QEHZPBE5HH")%7B%22data%22%3A%7B%22title%22%3A%22%E2%80%8B%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%20Golang%20%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%22%2C%22abstract%22%3A%22%E5%BC%95%E5%85%A5%E9%9A%8F%E7%9D%80%E5%B7%A5%E7%A8%8B%E5%8C%96%E5%BC%80%E5%8F%91%E7%9A%84%E5%86%85%E5%A4%A7%E5%8A%9B%E7%9A%84%E6%8E%A8%E5%B9%BF%EF%BC%8C%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%B6%8A%E6%9D%A5%E8%B6%8A%E5%8F%97%E5%88%B0%E5%B9%BF%E5%A4%A7%E5%BC%80%E5%8F%91%E8%80%85%E7%9A%84%E9%87%8D%E8%A7%86%E3%80%82%E5%9C%A8%E5%AD%A6%E4%B9%A0%E7%9A%84%E8%BF%87%E7%A8%8B%E4%B8%AD%EF%BC%8C%E5%8F%91%E7%8E%B0%E7%BD%91%E4%B8%8A%E9%92%88%E5%AF%B9%20Golang%20%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E5%A4%A7%E5%A4%9A%E4%BB%8E%E7%90%86%E8%AE%BA%E8%A7%92%E5%BA%A6%E5%87%BA%E5%8F%91%E4%BB%8B%E7%BB%8D%EF%BC%8C%E7%BC%BA%E4%B9%8F%E5%AE%8C%E6%95%B4%E7%9A%84%E5%AE%9E%E4%BE%8B%E8%AF%B4%E6%98%8E%EF%BC%8C%E6%99%A6%E6%B6%A9%E9%9A%BE%E6%87%82%E7%9A%84%20API%20%E8%AE%A9%E5%88%9D%E5%AD%A6%E6%8E%A5%E8%A7%A6%E8%80%85%E9%9A%BE%E4%BB%A5%E4%B8%8B%E6%89%8B%E3%80%82%22%2C%22articleType%22%3A%22article%22%2C%22itemId%22%3A%227194623951715303970%22%2C%22groupId%22%3A%227194623951715303970%22%2C%22groupSource%22%3A2%2C%22isOriginal%22%3Afalse%2C%22banComment%22%3Afalse%2C%22publishTime%22%3A%222023-01-31%2010%3A22%22%2C%22source%22%3A%22Freemen%E7%A8%8B%E5%BA%8F%E5%91%98%E6%8B%9B%E8%81%98app%22%2C%22tag%22%3A%22technique%22%2C%22mediaSite%22%3Anull%2C%22pathname%22%3A%22%2Farticle%2F7194623951715303970%2F%22%2C%22useCandle%22%3Afalse%2C%22isExclusive%22%3Afalse%2C%22favorite%22%3Afalse%2C%22relation%22%3A%7B%22isFollowing%22%3Afalse%2C%22isFollowed%22%3Afalse%7D%2C%22likeData%22%3A%7B%22userLikeStatus%22%3A0%2C%22count%22%3A76%7D%2C%22isSelf%22%3Afalse%2C%22content%22%3A%22%3Ch1%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%222%5C%22%3E%E5%BC%95%E5%85%A5%3C%2Fh1%3E%3Cp%20data-track%3D%5C%223%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E9%9A%8F%E7%9D%80%E5%B7%A5%E7%A8%8B%E5%8C%96%E5%BC%80%E5%8F%91%E7%9A%84%E5%86%85%E5%A4%A7%E5%8A%9B%E7%9A%84%E6%8E%A8%E5%B9%BF%EF%BC%8C%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%B6%8A%E6%9D%A5%E8%B6%8A%E5%8F%97%E5%88%B0%E5%B9%BF%E5%A4%A7%E5%BC%80%E5%8F%91%E8%80%85%E7%9A%84%E9%87%8D%E8%A7%86%E3%80%82%E5%9C%A8%E5%AD%A6%E4%B9%A0%E7%9A%84%E8%BF%87%E7%A8%8B%E4%B8%AD%EF%BC%8C%E5%8F%91%E7%8E%B0%E7%BD%91%E4%B8%8A%E9%92%88%E5%AF%B9%20Golang%20%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E5%A4%A7%E5%A4%9A%E4%BB%8E%E7%90%86%E8%AE%BA%E8%A7%92%E5%BA%A6%E5%87%BA%E5%8F%91%E4%BB%8B%E7%BB%8D%EF%BC%8C%E7%BC%BA%E4%B9%8F%E5%AE%8C%E6%95%B4%E7%9A%84%E5%AE%9E%E4%BE%8B%E8%AF%B4%E6%98%8E%EF%BC%8C%E6%99%A6%E6%B6%A9%E9%9A%BE%E6%87%82%E7%9A%84%20API%20%E8%AE%A9%E5%88%9D%E5%AD%A6%E6%8E%A5%E8%A7%A6%E8%80%85%E9%9A%BE%E4%BB%A5%E4%B8%8B%E6%89%8B%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%224%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%9C%AC%E7%AF%87%E4%B8%8D%E5%87%86%E5%A4%87%E5%A4%A7%E8%80%8C%E5%85%A8%E7%9A%84%E8%B0%88%E8%AE%BA%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E3%80%81%E7%AC%BC%E7%BB%9F%E7%9A%84%E4%BB%8B%E7%BB%8D%20Golang%20%E7%9A%84%E5%8D%95%E6%B5%8B%E5%B7%A5%E5%85%B7%EF%BC%8C%E8%80%8C%E5%B0%86%E4%BB%8E%20Golang%20%E5%8D%95%E6%B5%8B%E7%9A%84%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF%E5%87%BA%E5%8F%91%EF%BC%8C%E4%BB%A5%E6%9C%80%E7%AE%80%E5%8D%95%E4%B8%94%E5%AE%9E%E9%99%85%E7%9A%84%E4%BE%8B%E5%AD%90%E8%AE%B2%E8%A7%A3%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%E5%8D%95%E6%B5%8B%EF%BC%8C%E6%9C%80%E7%BB%88%E7%94%B1%E6%B5%85%E5%85%A5%E6%B7%B1%E6%8E%A2%E8%AE%A8%20go%20%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E4%B8%A4%E4%B8%AA%E6%AF%94%E8%BE%83%E7%BB%86%E8%8A%82%E7%9A%84%E9%97%AE%E9%A2%98%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%225%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9C%A8%E9%98%85%E8%AF%BB%E6%9C%AC%E6%96%87%E6%97%B6%EF%BC%8C%E8%AF%B7%E5%8A%A1%E5%BF%85%E5%AF%B9%20Golang%20%E7%9A%84%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E6%9C%89%E6%9C%80%E5%9F%BA%E6%9C%AC%E7%9A%84%E4%BA%86%E8%A7%A3%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Ch1%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%226%5C%22%3E%E4%B8%80%E6%AE%B5%E9%9C%80%E8%A6%81%E5%8D%95%E6%B5%8B%E7%9A%84%20Golang%20%E4%BB%A3%E7%A0%81%3C%2Fh1%3E%3Cpre%3E%3Ccode%3Epackage%20unit%5Cn%5Cnimport%20(%5Cn%20%26%2334%3Bencoding%2Fjson%26%2334%3B%5Cn%20%26%2334%3Berrors%26%2334%3B%5Cn%20%26%2334%3Bgithub.com%2Fgomodule%2Fredigo%2Fredis%26%2334%3B%5Cn%20%26%2334%3Bregexp%26%2334%3B%5Cn)%5Cn%5Cntype%20PersonDetail%20struct%20%7B%5Cn%20Username%20string%20%60json%3A%26%2334%3Busername%26%2334%3B%60%5Cn%20Email%20%20%20%20string%20%60json%3A%26%2334%3Bemail%26%2334%3B%60%5Cn%7D%5Cn%5Cn%2F%2F%20%E6%A3%80%E6%9F%A5%E7%94%A8%E6%88%B7%E5%90%8D%E6%98%AF%E5%90%A6%E9%9D%9E%E6%B3%95%5Cnfunc%20checkUsername(username%20string)%20bool%20%7B%5Cn%20const%20pattern%20%3D%20%60%5E%5Ba-z0-9_-%5D%7B3%2C16%7D%24%60%5Cn%5Cn%20reg%20%3A%3D%20regexp.MustCompile(pattern)%5Cn%20return%20reg.MatchString(username)%5Cn%7D%5Cn%5Cn%2F%2F%20%E6%A3%80%E6%9F%A5%E7%94%A8%E6%88%B7%E9%82%AE%E7%AE%B1%E6%98%AF%E5%90%A6%E9%9D%9E%E6%B3%95%5Cnfunc%20checkEmail(email%20string)%20bool%20%7B%5Cn%20const%20pattern%20%3D%20%60%5E%5Ba-zA-Z0-9_-%5D%2B%40%5Ba-zA-Z0-9_-%5D%2B(%5C%5C.%5Ba-zA-Z0-9_-%5D%2B)%2B%24%60%5Cn%5Cn%20reg%20%3A%3D%20regexp.MustCompile(pattern)%5Cn%20return%20reg.MatchString(email)%5Cn%7D%5Cn%5Cn%2F%2F%20%E9%80%9A%E8%BF%87%20redis%20%E6%8B%89%E5%8F%96%E5%AF%B9%E5%BA%94%E7%94%A8%E6%88%B7%E7%9A%84%E8%B5%84%E6%96%99%E4%BF%A1%E6%81%AF%5Cnfunc%20getPersonDetailRedis(username%20string)%20(*PersonDetail%2C%20error)%20%7B%5Cn%20result%20%3A%3D%20%26PersonDetail%7B%7D%5Cn%5Cn%20client%2C%20err%20%3A%3D%20redis.Dial(%26%2334%3Btcp%26%2334%3B%2C%20%26%2334%3B%3A6379%26%2334%3B)%5Cn%20defer%20client.Close()%5Cn%20data%2C%20err%20%3A%3D%20redis.Bytes(client.Do(%26%2334%3BGET%26%2334%3B%2C%20username))%5Cn%5Cn%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20return%20nil%2C%20err%5Cn%20%7D%5Cn%5Cn%20err%20%3D%20json.Unmarshal(data%2C%20result)%5Cn%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20return%20nil%2C%20err%5Cn%20%7D%5Cn%5Cn%20return%20result%2C%20nil%5Cn%7D%5Cn%5Cn%2F%2F%20%E6%8B%89%E5%8F%96%E7%94%A8%E6%88%B7%E8%B5%84%E6%96%99%E4%BF%A1%E6%81%AF%E5%B9%B6%E6%A0%A1%E9%AA%8C%5Cnfunc%20GetPersonDetail(username%20string)%20(*PersonDetail%2C%20error)%20%7B%5Cn%20%2F%2F%20%E6%A3%80%E6%9F%A5%E7%94%A8%E6%88%B7%E5%90%8D%E6%98%AF%E5%90%A6%E6%9C%89%E6%95%88%5Cn%20if%20ok%20%3A%3D%20checkUsername(username)%3B%20!ok%20%7B%5Cn%20%20return%20nil%2C%20errors.New(%26%2334%3Binvalid%20username%26%2334%3B)%5Cn%20%7D%5Cn%5Cn%20%2F%2F%20%E4%BB%8E%20redis%20%E6%8E%A5%E5%8F%A3%E8%8E%B7%E5%8F%96%E4%BF%A1%E6%81%AF%5Cn%20detail%2C%20err%20%3A%3D%20getPersonDetailRedis(username)%5Cn%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20return%20nil%2C%20err%5Cn%20%7D%5Cn%5Cn%20%2F%2F%20%E6%A0%A1%E9%AA%8C%5Cn%20if%20ok%20%3A%3D%20checkEmail(detail.Email)%3B%20!ok%20%7B%5Cn%20%20return%20nil%2C%20errors.New(%26%2334%3Binvalid%20email%26%2334%3B)%5Cn%20%7D%5Cn%5Cn%20return%20detail%2C%20nil%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%228%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%BF%99%E6%98%AF%E4%B8%80%E6%AE%B5%E5%85%B8%E5%9E%8B%E7%9A%84%E6%9C%89%20I%2FO%20%E7%9A%84%E5%8A%9F%E8%83%BD%E4%BB%A3%E7%A0%81%EF%BC%8C%E4%B8%BB%E4%BD%93%E5%8A%9F%E8%83%BD%E6%98%AF%E4%BC%A0%E5%85%A5%E7%94%A8%E6%88%B7%E5%90%8D%EF%BC%8C%E6%A0%A1%E9%AA%8C%E5%90%88%E6%B3%95%E6%80%A7%E4%B9%8B%E5%90%8E%E9%80%9A%E8%BF%87%20redis%20%E8%8E%B7%E5%8F%96%E4%BF%A1%E6%81%AF%EF%BC%8C%E4%B9%8B%E5%90%8E%E6%A0%A1%E9%AA%8C%E8%8E%B7%E5%8F%96%E5%80%BC%E5%86%85%E5%AE%B9%E7%9A%84%E5%90%88%E6%B3%95%E6%80%A7%E5%90%8E%E5%B9%B6%E8%BF%94%E5%9B%9E%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Ch1%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%229%5C%22%3E%E5%90%8E%E5%8F%B0%E6%9C%8D%E5%8A%A1%E5%8D%95%E6%B5%8B%E5%9C%BA%E6%99%AF%3C%2Fh1%3E%3Cp%20data-track%3D%5C%2210%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AF%B9%E4%BA%8E%E4%B8%80%E4%B8%AA%E4%BC%A0%E7%BB%9F%E7%9A%84%E5%90%8E%E7%AB%AF%E6%9C%8D%E5%8A%A1%EF%BC%8C%E5%AE%83%E4%B8%BB%E8%A6%81%E6%9C%89%E4%BB%A5%E4%B8%8B%E5%87%A0%E7%82%B9%E7%9A%84%E8%81%8C%E8%B4%A3%E5%92%8C%E5%8A%9F%E8%83%BD%EF%BC%9A%3C%2Fspan%3E%3C%2Fp%3E%3Cul%3E%3Cli%20data-track%3D%5C%2211%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%8E%A5%E6%94%B6%E5%A4%96%E9%83%A8%E8%AF%B7%E6%B1%82%EF%BC%8Ccontroller%20%E5%B1%82%E5%88%86%E5%8F%91%E8%AF%B7%E6%B1%82%E3%80%81%E6%A0%A1%E9%AA%8C%E8%AF%B7%E6%B1%82%E5%8F%82%E6%95%B0%3C%2Fspan%3E%3C%2Fli%3E%3Cli%20data-track%3D%5C%2212%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%AF%B7%E6%B1%82%E6%9C%89%E6%95%88%E5%88%86%E5%8F%91%E5%90%8E%EF%BC%8C%E5%9C%A8%20service%20%E5%B1%82%E4%B8%8E%20dao%20%E5%B1%82%E8%BF%9B%E8%A1%8C%E4%BA%A4%E4%BA%92%E5%90%8E%E5%81%9A%E9%80%BB%E8%BE%91%E5%A4%84%E7%90%86%3C%2Fspan%3E%3C%2Fli%3E%3Cli%20data-track%3D%5C%2213%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3Edao%20%E5%B1%82%E8%B4%9F%E8%B4%A3%E6%95%B0%E6%8D%AE%E6%93%8D%E4%BD%9C%EF%BC%8C%E4%B8%BB%E8%A6%81%E6%98%AF%E6%95%B0%E6%8D%AE%E5%BA%93%E6%88%96%E6%8C%81%E4%B9%85%E5%8C%96%E5%AD%98%E5%82%A8%E7%9B%B8%E5%85%B3%E7%9A%84%E6%93%8D%E4%BD%9C%3C%2Fspan%3E%3C%2Fli%3E%3C%2Ful%3E%3Cp%20data-track%3D%5C%2214%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9B%A0%E6%AD%A4%EF%BC%8C%E4%BB%8E%E8%81%8C%E8%B4%A3%E5%87%BA%E5%8F%91%E6%9D%A5%E7%9C%8B%EF%BC%8C%E5%9C%A8%E5%81%9A%E5%90%8E%E5%8F%B0%E5%8D%95%E6%B5%8B%E4%B8%AD%EF%BC%8C%E6%A0%B8%E5%BF%83%E4%B8%BB%E8%A6%81%E6%98%AF%E9%AA%8C%E8%AF%81%20service%20%E5%B1%82%E5%92%8C%20dao%20%E5%B1%82%E7%9A%84%E7%9B%B8%E5%85%B3%E9%80%BB%E8%BE%91%EF%BC%8C%E6%AD%A4%E5%A4%96%20controller%20%E5%B1%82%E7%9A%84%E5%8F%82%E6%95%B0%E6%A0%A1%E9%AA%8C%E4%B9%9F%E5%9C%A8%E5%8D%95%E6%B5%8B%E4%B9%8B%E4%B8%AD%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2215%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%BB%86%E5%88%86%E6%9D%A5%E7%9C%8B%EF%BC%8C%E5%AF%B9%E4%BA%8E%E7%9B%B8%E5%85%B3%E9%80%BB%E8%BE%91%E7%9A%84%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%EF%BC%8C%E7%AC%94%E8%80%85%E5%80%BE%E5%90%91%E4%BA%8E%E6%8A%8A%E5%8D%95%E6%B5%8B%E5%88%86%E4%B8%BA%E4%B8%A4%E7%A7%8D%EF%BC%9A%3C%2Fspan%3E%3C%2Fp%3E%3Cul%3E%3Cli%20data-track%3D%5C%2216%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%97%A0%E7%AC%AC%E4%B8%89%E6%96%B9%E4%BE%9D%E8%B5%96%EF%BC%8C%E7%BA%AF%E9%80%BB%E8%BE%91%E4%BB%A3%E7%A0%81%3C%2Fspan%3E%3C%2Fli%3E%3Cli%20data-track%3D%5C%2217%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%9C%89%E7%AC%AC%E4%B8%89%E6%96%B9%E4%BE%9D%E8%B5%96%EF%BC%8C%E5%A6%82%E6%96%87%E4%BB%B6%E3%80%81%E7%BD%91%E7%BB%9C%20I%2FO%E3%80%81%E7%AC%AC%E4%B8%89%E6%96%B9%E4%BE%9D%E8%B5%96%E5%BA%93%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93%E6%93%8D%E4%BD%9C%E7%9B%B8%E5%85%B3%E7%9A%84%E4%BB%A3%E7%A0%81%3C%2Fspan%3E%3C%2Fli%3E%3C%2Ful%3E%3Cp%20data-track%3D%5C%2218%5C%22%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%B3%A8%EF%BC%9A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E5%8F%AA%E6%98%AF%E9%92%88%E5%AF%B9%E5%8D%95%E4%B8%AA%E5%87%BD%E6%95%B0%E7%9A%84%E6%B5%8B%E8%AF%95%EF%BC%8C%E5%85%B3%E6%B3%A8%E5%85%B6%E5%86%85%E9%83%A8%E7%9A%84%E9%80%BB%E8%BE%91%EF%BC%8C%E5%AF%B9%E4%BA%8E%E7%BD%91%E7%BB%9C%2F%E6%95%B0%E6%8D%AE%E5%BA%93%E8%AE%BF%E9%97%AE%E7%AD%89%EF%BC%8C%E9%9C%80%E8%A6%81%E9%80%9A%E8%BF%87%E7%9B%B8%E5%BA%94%E7%9A%84%E6%89%8B%E6%AE%B5%E8%BF%9B%E8%A1%8C%20mock%E3%80%82%3C%2Fspan%3E%3C%2Fstrong%3E%3C%2Fp%3E%3Ch1%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2219%5C%22%3EGolang%20%E5%8D%95%E6%B5%8B%E5%B7%A5%E5%85%B7%E9%80%89%E5%9E%8B%3C%2Fh1%3E%3Cp%20data-track%3D%5C%2220%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%94%B1%E4%BA%8E%E6%88%91%E4%BB%AC%E6%8A%8A%E5%8D%95%E6%B5%8B%E7%AE%80%E5%8D%95%E7%9A%84%E5%88%86%E4%B8%BA%E4%BA%86%E4%B8%A4%E7%A7%8D%EF%BC%9A%3C%2Fspan%3E%3C%2Fp%3E%3Cul%3E%3Cli%20data-track%3D%5C%2221%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AF%B9%E4%BA%8E%E6%97%A0%E7%AC%AC%E4%B8%89%E6%96%B9%E4%BE%9D%E8%B5%96%E7%9A%84%E7%BA%AF%E9%80%BB%E8%BE%91%E4%BB%A3%E7%A0%81%EF%BC%8C%E6%88%91%E4%BB%AC%E5%8F%AA%E9%9C%80%E8%A6%81%E9%AA%8C%E8%AF%81%3C%2Fspan%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%9B%B8%E5%85%B3%E9%80%BB%E8%BE%91%3C%2Fspan%3E%3C%2Fstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%8D%B3%E5%8F%AF%EF%BC%8C%E8%BF%99%E9%87%8C%E5%8F%AA%E9%9C%80%E8%A6%81%E4%BD%BF%E7%94%A8%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Easser%3C%2Fspan%3E%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%231E6BB8%3B%5C%22%3Et%3C%2Fspan%3E%20%3Cstrong%3E%EF%BC%88%E6%96%AD%E8%A8%80%EF%BC%89%3C%2Fstrong%3E%EF%BC%8C%E9%80%9A%E8%BF%87%E6%8E%A7%E5%88%B6%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA%E6%AF%94%E5%AF%B9%E7%BB%93%E6%9E%9C%E5%8D%B3%E5%8F%AF%E3%80%82%3C%2Fli%3E%3Cli%20data-track%3D%5C%2222%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AF%B9%E4%BA%8E%E6%9C%89%E7%AC%AC%E4%B8%89%E6%96%B9%E4%BE%9D%E8%B5%96%E7%9A%84%E4%BB%A3%E7%A0%81%EF%BC%8C%E5%9C%A8%E9%AA%8C%E8%AF%81%E7%9B%B8%E5%85%B3%E4%BB%A3%E7%A0%81%E9%80%BB%E8%BE%91%E4%B9%8B%E5%89%8D%EF%BC%8C%E6%88%91%E4%BB%AC%E9%9C%80%E8%A6%81%E5%B0%86%E7%9B%B8%E5%85%B3%E7%9A%84%E4%BE%9D%E8%B5%96%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%20%3C%2Fspan%3E%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Emock%3C%2Fspan%3E%3C%2Fspan%3E%20%3Cstrong%3E%EF%BC%88%E6%A8%A1%E6%8B%9F%EF%BC%89%3C%2Fstrong%3E%EF%BC%8C%E4%B9%8B%E5%90%8E%E6%89%8D%E8%83%BD%E9%80%9A%E8%BF%87%E6%96%AD%E8%A8%80%E9%AA%8C%E8%AF%81%E9%80%BB%E8%BE%91%E3%80%82%E8%BF%99%E9%87%8C%E9%9C%80%E8%A6%81%E5%80%9F%E5%8A%A9%E7%AC%AC%E4%B8%89%E6%96%B9%E5%B7%A5%E5%85%B7%E5%BA%93%E6%9D%A5%E5%A4%84%E7%90%86%E3%80%82%3C%2Fli%3E%3C%2Ful%3E%3Cp%20data-track%3D%5C%2223%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9B%A0%E6%AD%A4%EF%BC%8C%E5%AF%B9%E4%BA%8E%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Eassert%3C%2Fspan%3E%3C%2Fspan%3E%20%3Cstrong%3E%EF%BC%88%E6%96%AD%E8%A8%80%EF%BC%89%3C%2Fstrong%3E%E5%B7%A5%E5%85%B7%EF%BC%8C%E5%8F%AF%E4%BB%A5%E9%80%89%E6%8B%A9%20testify%20%E6%88%96%20convery%EF%BC%8C%E7%AC%94%E8%80%85%E8%BF%99%E9%87%8C%E9%80%89%E6%8B%A9%E4%BA%86%20testify%E3%80%82%E5%AF%B9%E4%BA%8E%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Emock%3C%2Fspan%3E%3C%2Fspan%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%20%3C%2Fspan%3E%3Cstrong%3E%EF%BC%88%E6%A8%A1%E6%8B%9F%EF%BC%89%3C%2Fstrong%3E%E5%B7%A5%E5%85%B7%EF%BC%8C%E7%AC%94%E8%80%85%E8%BF%99%E9%87%8C%E9%80%89%E6%8B%A9%E4%BA%86%20gomock%20%E5%92%8C%20gomonkey%E3%80%82%E5%85%B3%E4%BA%8E%20mock%20%E5%B7%A5%E5%85%B7%E5%90%8C%E6%97%B6%E4%BD%BF%E7%94%A8%20gomock%20%E5%92%8C%20gomonkey%EF%BC%8C%E8%BF%99%E9%87%8C%E8%B7%9F%20Golang%20%E7%9A%84%E8%AF%AD%E8%A8%80%E7%89%B9%E6%80%A7%E6%9C%89%E5%85%B3%EF%BC%8C%E4%B8%8B%E9%9D%A2%E4%BC%9A%E8%AF%A6%E7%BB%86%E7%9A%84%E8%AF%B4%E6%98%8E%E3%80%82%3C%2Fp%3E%3Ch1%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2224%5C%22%3E%E5%AE%8C%E5%96%84%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B%3C%2Fh1%3E%3Cp%20data-track%3D%5C%2225%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%BF%99%E9%87%8C%E6%88%91%E4%BB%AC%E5%BC%80%E5%A7%8B%E5%AF%B9%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81%E4%B8%AD%E7%9A%84%E5%87%BD%E6%95%B0%E5%81%9A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2226%5C%22%3E%3Cspan%20style%3D%5C%22font-size%3A%201.118em%3B%5C%22%3E%3Cstrong%3E%E7%94%9F%E6%88%90%E5%8D%95%E6%B5%8B%E6%A8%A1%E6%9D%BF%E4%BB%A3%E7%A0%81%3C%2Fstrong%3E%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2227%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E9%A6%96%E5%85%88%E5%9C%A8%20Goland%20%E4%B8%AD%E6%89%93%E5%BC%80%E9%A1%B9%E7%9B%AE%EF%BC%8C%E5%8A%A0%E8%BD%BD%E5%AF%B9%E5%BA%94%E6%96%87%E4%BB%B6%E5%90%8E%E5%8F%B3%E9%94%AE%E6%89%BE%E5%88%B0%20Generate%20%E9%A1%B9%EF%BC%8C%E7%82%B9%E5%87%BB%E5%90%8E%E9%80%89%E6%8B%A9%20Tests%20for%20package%EF%BC%8C%E4%B9%8B%E5%90%8E%E7%94%9F%E6%88%90%E4%BB%A5%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E_test.go%3C%2Fspan%3E%3C%2Fspan%3E%20%E7%BB%93%E5%B0%BE%E7%9A%84%E5%8D%95%E6%B5%8B%E6%96%87%E4%BB%B6%E3%80%82%EF%BC%88%E5%A6%82%E6%9E%9C%E6%83%B3%E9%92%88%E5%AF%B9%E6%9F%90%E4%B8%80%E7%89%B9%E5%AE%9A%E5%87%BD%E6%95%B0%E5%81%9A%E5%8D%95%E6%B5%8B%EF%BC%8C%E8%AF%B7%E9%80%89%E6%8B%A9%E5%AF%B9%E5%BA%94%E7%9A%84%E5%87%BD%E6%95%B0%E5%90%8E%E5%8F%B3%E9%94%AE%E9%80%89%E5%AE%9A%20Generate%20%E9%A1%B9%E6%89%A7%E8%A1%8C%20Tests%20for%20selection%E3%80%82%EF%BC%89%3C%2Fp%3E%3Cp%20data-track%3D%5C%2228%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%BF%99%E9%87%8C%E5%B1%95%E7%A4%BA%E9%80%9A%E8%BF%87%20IDE%20%E7%94%9F%E6%88%90%E7%9A%84%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%20%3C%2Fspan%3E%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3ETestGetPersonDetail%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%B5%8B%E8%AF%95%E5%87%BD%E6%95%B0%EF%BC%9A%3C%2Fp%3E%3Cpre%3E%3Ccode%3Epackage%20unit%5Cn%5Cnimport%20(%5Cn%20%20%26%2334%3Breflect%26%2334%3B%5Cn%20%20%26%2334%3Btesting%26%2334%3B%5Cn)%5Cn%5Cnfunc%20TestGetPersonDetail(t%20*testing.T)%20%7B%5Cn%20type%20args%20struct%20%7B%5Cn%20%20username%20string%5Cn%20%7D%5Cn%20tests%20%3A%3D%20%5B%5Dstruct%20%7B%5Cn%20%20name%20%20%20%20string%5Cn%20%20args%20%20%20%20args%5Cn%20%20want%20%20%20%20*PersonDetail%5Cn%20%20wantErr%20bool%5Cn%20%7D%7B%5Cn%20%20%2F%2F%20TODO%3A%20Add%20test%20cases.%5Cn%20%7D%5Cn%20for%20_%2C%20tt%20%3A%3D%20range%20tests%20%7B%5Cn%20%20t.Run(tt.name%2C%20func(t%20*testing.T)%20%7B%5Cn%20%20%20got%2C%20err%20%3A%3D%20GetPersonDetail(tt.args.username)%5Cn%20%20%20if%20(err%20!%3D%20nil)%20!%3D%20tt.wantErr%20%7B%5Cn%20%20%20%20t.Errorf(%26%2334%3BGetPersonDetail()%20error%20%3D%20%25v%2C%20wantErr%20%25v%26%2334%3B%2C%20err%2C%20tt.wantErr)%5Cn%20%20%20%20return%5Cn%20%20%20%7D%5Cn%20%20%20if%20!reflect.DeepEqual(got%2C%20tt.want)%20%7B%5Cn%20%20%20%20t.Errorf(%26%2334%3BGetPersonDetail()%20got%20%3D%20%25v%2C%20want%20%25v%26%2334%3B%2C%20got%2C%20tt.want)%5Cn%20%20%20%7D%5Cn%20%20%7D)%5Cn%20%7D%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2230%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%94%B1%20Goland%20%E7%94%9F%E6%88%90%E7%9A%84%E5%8D%95%E6%B5%8B%E6%A8%A1%E6%9D%BF%E4%BB%A3%E7%A0%81%E4%BD%BF%E7%94%A8%E7%9A%84%E6%98%AF%E5%AE%98%E6%96%B9%E7%9A%84%20testing%20%E6%A1%86%E6%9E%B6%EF%BC%8C%E4%B8%BA%E4%BA%86%E6%9B%B4%E6%96%B9%E4%BE%BF%E7%9A%84%E6%96%AD%E8%A8%80%EF%BC%8C%E6%88%91%E4%BB%AC%E6%8A%8A%20testing%20%E6%94%B9%E9%80%A0%E6%88%90%20testify%20%E7%9A%84%E6%96%AD%E8%A8%80%E6%96%B9%E5%BC%8F%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2231%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%BF%99%E9%87%8C%E5%85%B6%E5%AE%9E%E5%8F%AA%E9%9C%80%E8%A6%81%E5%BC%95%E5%85%A5%20testify%20%E5%90%8E%E4%BF%AE%E6%94%B9%20test%20%E5%87%BD%E6%95%B0%E6%9C%80%E5%90%8E%E7%9A%84%E6%96%AD%E8%A8%80%E4%BB%A3%E7%A0%81%E5%8D%B3%E5%8F%AF%EF%BC%8C%E8%BF%99%E9%87%8C%E6%88%91%E4%BB%AC%E4%BB%A5%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3ETestGetPersonDetail%3C%2Fspan%3E%3C%2Fspan%3E%20%E4%B8%BA%E4%BE%8B%E5%AD%90%EF%BC%8C%E5%85%B6%E4%BB%96%E5%87%BD%E6%95%B0%E4%B8%8D%E8%B5%98%E8%BF%B0%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3Epackage%20unit%5Cnimport%20(%5Cn%20%20%26%2334%3Bgithub.com%2Fstretchr%2Ftestify%2Fassert%26%2334%3B%20%2F%2F%20%E8%BF%99%E9%87%8C%E5%BC%95%E5%85%A5%E4%BA%86%20testify%5Cn%20%20%26%2334%3Breflect%26%2334%3B%5Cn%20%20%26%2334%3Btesting%26%2334%3B%5Cn)%5Cn%5Cnfunc%20TestGetPersonDetail(t%20*testing.T)%20%7B%5Cn%20type%20args%20struct%20%7B%5Cn%20%20username%20string%5Cn%20%7D%5Cn%20tests%20%3A%3D%20%5B%5Dstruct%20%7B%5Cn%20%20name%20%20%20%20string%5Cn%20%20args%20%20%20%20args%5Cn%20%20want%20%20%20%20*PersonDetail%5Cn%20%20wantErr%20bool%5Cn%20%7D%7B%5Cn%20%20%2F%2F%20TODO%3A%20Add%20test%20cases.%5Cn%20%7D%5Cn%20for%20_%2C%20tt%20%3A%3D%20range%20tests%20%7B%5Cn%20%20got%2C%20err%20%3A%3D%20GetPersonDetail(tt.args.username)%5Cn%20%20%2F%2F%20%E6%94%B9%E5%86%99%E8%BF%99%E9%87%8C%E6%96%AD%E8%A8%80%E7%9A%84%E6%96%B9%E5%BC%8F%E5%8D%B3%E5%8F%AF%5Cn%20%20assert.Equal(t%2C%20tt.want%2C%20got)%5Cn%20%20assert.Equal(t%2C%20tt.wantErr%2C%20err%20!%3D%20nil)%5Cn%20%7D%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2233%5C%22%3E%3Cspan%20style%3D%5C%22font-size%3A%201.118em%3B%5C%22%3E%3Cstrong%3E%E5%88%86%E6%9E%90%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B%3C%2Fstrong%3E%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2234%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AF%B9%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EcheckUsername%3C%2Fspan%3E%3C%2Fspan%3E%20%E3%80%81%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EcheckEmail%3C%2Fspan%3E%3C%2Fspan%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%20%3C%2Fspan%3E%E7%BA%AF%E9%80%BB%E8%BE%91%E5%87%BD%E6%95%B0%E7%BC%96%E5%86%99%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B%EF%BC%8C%E8%BF%99%E9%87%8C%E4%BB%A5%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EcheckEmail%3C%2Fspan%3E%3C%2Fspan%3E%20%E4%B8%BA%E4%BE%8B%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3Efunc%20Test_checkEmail(t%20*testing.T)%20%7B%5Cn%20type%20args%20struct%20%7B%5Cn%20%20email%20string%5Cn%20%7D%5Cn%20tests%20%3A%3D%20%5B%5Dstruct%20%7B%5Cn%20%20name%20string%5Cn%20%20args%20args%5Cn%20%20want%20bool%5Cn%20%7D%7B%5Cn%20%20%7B%5Cn%20%20%20name%3A%20%26%2334%3Bemail%20valid%26%2334%3B%2C%5Cn%20%20%20args%3A%20args%7B%5Cn%20%20%20%20email%3A%20%26%2334%3B1234567%40qq.com%26%2334%3B%2C%5Cn%20%20%20%7D%2C%5Cn%20%20%20want%3A%20true%2C%5Cn%20%20%7D%2C%5Cn%20%20%7B%5Cn%20%20%20name%3A%20%26%2334%3Bemail%20invalid%26%2334%3B%2C%5Cn%20%20%20args%3A%20args%7B%5Cn%20%20%20%20email%3A%20%26%2334%3Btest.com%26%2334%3B%2C%5Cn%20%20%20%7D%2C%5Cn%20%20%20want%3A%20false%2C%5Cn%20%20%7D%2C%5Cn%20%7D%5Cn%20for%20_%2C%20tt%20%3A%3D%20range%20tests%20%7B%5Cn%20%20got%20%3A%3D%20checkEmail(tt.args.email)%5Cn%20%20assert.Equal(t%2C%20tt.want%2C%20got)%5Cn%20%7D%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2236%5C%22%3E%3Cspan%20style%3D%5C%22font-size%3A%201.118em%3B%5C%22%3E%3Cstrong%3E%E4%BD%BF%E7%94%A8%20gomonkey%20%E6%89%93%E6%A1%A9%3C%2Fstrong%3E%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2237%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AF%B9%E4%BA%8E%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EGetPersonDetail%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E8%80%8C%E8%A8%80%EF%BC%8C%E8%AF%A5%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E4%BA%86%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EgetPersonDetailRedis%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E8%8E%B7%E5%8F%96%E5%85%B7%E4%BD%93%E7%9A%84%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EPersonDetail%3C%2Fspan%3E%3C%2Fspan%3E%20%E4%BF%A1%E6%81%AF%E3%80%82%E4%B8%BA%E6%AD%A4%EF%BC%8C%E6%88%91%E4%BB%AC%E9%9C%80%E8%A6%81%E4%B8%BA%E5%AE%83%E6%89%93%E4%B8%80%E4%B8%AA%E2%80%9C%E6%A1%A9%E2%80%9D%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2238%5C%22%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%89%80%E8%B0%93%E7%9A%84%E2%80%9C%E6%A1%A9%E2%80%9D%EF%BC%8C%E4%B9%9F%E5%8F%AB%E5%81%9A%E2%80%9C%E6%A1%A9%E4%BB%A3%E7%A0%81%E2%80%9D%EF%BC%8C%E6%98%AF%E6%8C%87%E7%94%A8%E6%9D%A5%E4%BB%A3%E6%9B%BF%E5%85%B3%E8%81%94%E4%BB%A3%E7%A0%81%E6%88%96%E8%80%85%E6%9C%AA%E5%AE%9E%E7%8E%B0%E4%BB%A3%E7%A0%81%E7%9A%84%E4%BB%A3%E7%A0%81%E3%80%82%3C%2Fspan%3E%3C%2Fstrong%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2239%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AF%B9%E4%BA%8E%E5%87%BD%E6%95%B0%E3%80%81%E6%88%90%E5%91%98%E6%96%B9%E6%B3%95%E6%88%96%E8%80%85%E6%98%AF%E5%8F%98%E9%87%8F%E7%9A%84%E6%89%93%E6%A1%A9%EF%BC%8C%E6%88%91%E4%BB%AC%E9%80%9A%E5%B8%B8%E4%BD%BF%E7%94%A8%20gomonkey%20%E6%9D%A5%E8%BF%9B%E8%A1%8C%E6%89%93%E6%A1%A9%E3%80%82%E5%85%B7%E4%BD%93%20API%20%E8%AF%B7%E5%8F%82%E8%80%83%EF%BC%9Ahttps%3A%2F%2Fpkg.go.dev%2Fgithub.com%2Fagiledragon%2Fgomonkey%3C%2Fspan%3E%3C%2Fp%3E%3Cpre%3E%3Ccode%3E%2F%2F%20%E6%8B%89%E5%8F%96%E7%94%A8%E6%88%B7%E8%B5%84%E6%96%99%E4%BF%A1%E6%81%AF%E5%B9%B6%E6%A0%A1%E9%AA%8C%5Cnfunc%20GetPersonDetail(username%20string)%20(*PersonDetail%2C%20error)%20%7B%5Cn%20%2F%2F%20%E6%A3%80%E6%9F%A5%E7%94%A8%E6%88%B7%E5%90%8D%E6%98%AF%E5%90%A6%E6%9C%89%E6%95%88%5Cn%20if%20ok%20%3A%3D%20checkUsername(username)%3B%20!ok%20%7B%5Cn%20%20return%20nil%2C%20errors.New(%26%2334%3Binvalid%20username%26%2334%3B)%5Cn%20%7D%5Cn%5Cn%20%2F%2F%20%E4%BB%8E%20redis%20%E6%8E%A5%E5%8F%A3%E8%8E%B7%E5%8F%96%E4%BF%A1%E6%81%AF%5Cn%20detail%2C%20err%20%3A%3D%20getPersonDetailRedis(username)%5Cn%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20return%20nil%2C%20err%5Cn%20%7D%5Cn%5Cn%20%2F%2F%20%E6%A0%A1%E9%AA%8C%5Cn%20if%20ok%20%3A%3D%20checkEmail(detail.Email)%3B%20!ok%20%7B%5Cn%20%20return%20nil%2C%20errors.New(%26%2334%3Binvalid%20email%26%2334%3B)%5Cn%20%7D%5Cn%5Cn%20return%20detail%2C%20nil%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2241%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%BB%8E%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EGetPersonDetail%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E5%8F%AF%E8%A7%81%EF%BC%8C%E4%B8%BA%E4%BA%86%E8%83%BD%E5%A4%9F%E5%AE%8C%E5%85%A8%E8%A6%86%E7%9B%96%E8%AF%A5%E5%87%BD%E6%95%B0%EF%BC%8C%E6%88%91%E4%BB%AC%E9%9C%80%E8%A6%81%E6%8E%A7%E5%88%B6%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EgetPersonDetailRedis%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E4%B8%8D%E5%90%8C%E7%9A%84%E8%BE%93%E5%87%BA%E6%9D%A5%E4%BF%9D%E8%AF%81%E5%90%8E%E7%BB%AD%E4%BB%A3%E7%A0%81%E9%83%BD%E8%83%BD%E5%A4%9F%E8%A2%AB%E8%A6%86%E7%9B%96%E8%BF%90%E8%A1%8C%E5%88%B0%E3%80%82%E5%9B%A0%E6%AD%A4%EF%BC%8C%E8%BF%99%E9%87%8C%E9%9C%80%E8%A6%81%E4%BD%BF%E7%94%A8%20gomonkey%20%E6%9D%A5%E7%BB%99%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EgetPersonDetailRedis%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E6%89%93%E4%B8%80%E4%B8%AA%E2%80%9C%E6%A1%A9%E5%BA%8F%E5%88%97%E2%80%9D%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2242%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%89%80%E8%B0%93%E7%9A%84%E5%87%BD%E6%95%B0%E2%80%9C%E6%A1%A9%E5%BA%8F%E5%88%97%E2%80%9D%E6%8C%87%E7%9A%84%E6%98%AF%E6%8F%90%E5%89%8D%E6%8C%87%E5%AE%9A%E5%A5%BD%E8%B0%83%E7%94%A8%E5%87%BD%E6%95%B0%E7%9A%84%E8%BF%94%E5%9B%9E%E5%80%BC%E5%BA%8F%E5%88%97%EF%BC%8C%E5%BD%93%E8%AF%A5%E5%87%BD%E6%95%B0%E5%A4%9A%E6%AC%A1%E8%B0%83%E7%94%A8%E6%97%B6%E5%80%99%EF%BC%8C%E8%83%BD%E5%A4%9F%E6%8C%89%E7%85%A7%E5%8E%9F%E5%85%88%E6%8C%87%E5%AE%9A%E7%9A%84%E8%BF%94%E5%9B%9E%E5%80%BC%E5%BA%8F%E5%88%97%E4%BE%9D%E6%AC%A1%E8%BF%94%E5%9B%9E%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cpre%3E%3Ccode%3Efunc%20TestGetPersonDetail(t%20*testing.T)%20%7B%5Cn%20type%20args%20struct%20%7B%5Cn%20%20username%20string%5Cn%20%7D%5Cn%20tests%20%3A%3D%20%5B%5Dstruct%20%7B%5Cn%20%20name%20%20%20%20string%5Cn%20%20args%20%20%20%20args%5Cn%20%20want%20%20%20%20*PersonDetail%5Cn%20%20wantErr%20bool%5Cn%20%7D%7B%5Cn%20%20%7Bname%3A%20%26%2334%3Binvalid%20username%26%2334%3B%2C%20args%3A%20args%7Busername%3A%20%26%2334%3Bsteven%20xxx%26%2334%3B%7D%2C%20want%3A%20nil%2C%20wantErr%3A%20true%7D%2C%5Cn%20%20%7Bname%3A%20%26%2334%3Binvalid%20email%26%2334%3B%2C%20args%3A%20args%7Busername%3A%20%26%2334%3Binvalid_email%26%2334%3B%7D%2C%20want%3A%20nil%2C%20wantErr%3A%20true%7D%2C%5Cn%20%20%7Bname%3A%20%26%2334%3Bthrow%20err%26%2334%3B%2C%20args%3A%20args%7Busername%3A%20%26%2334%3Bthrow_err%26%2334%3B%7D%2C%20want%3A%20nil%2C%20wantErr%3A%20true%7D%2C%5Cn%20%20%7Bname%3A%20%26%2334%3Bvalid%20return%26%2334%3B%2C%20args%3A%20args%7Busername%3A%20%26%2334%3Bsteven%26%2334%3B%7D%2C%20want%3A%20%26PersonDetail%7BUsername%3A%20%26%2334%3Bsteven%26%2334%3B%2C%20Email%3A%20%26%2334%3B12345678%40qq.com%26%2334%3B%7D%2C%20wantErr%3A%20false%7D%2C%5Cn%20%7D%5Cn%5Cn%20%2F%2F%20%E4%B8%BA%E5%87%BD%E6%95%B0%E6%89%93%E6%A1%A9%E5%BA%8F%E5%88%97%5Cn%20%2F%2F%20%E4%BD%BF%E7%94%A8%20gomonkey%20%E6%89%93%E5%87%BD%E6%95%B0%E6%A1%A9%E5%BA%8F%E5%88%97%5Cn%20%2F%2F%20%E7%AC%AC%E4%B8%80%E4%B8%AA%E7%94%A8%E4%BE%8B%E4%B8%8D%E4%BC%9A%E8%B0%83%E7%94%A8%20getPersonDetailRedis%EF%BC%8C%E6%89%80%E4%BB%A5%E5%8F%AA%E9%9C%80%E8%A6%81%203%20%E4%B8%AA%E5%80%BC%5Cn%20outputs%20%3A%3D%20%5B%5Dgomonkey.OutputCell%7B%5Cn%20%20%7B%5Cn%20%20%20Values%3A%20gomonkey.Params%7B%26PersonDetail%7BUsername%3A%20%26%2334%3Binvalid_email%26%2334%3B%2C%20Email%3A%20%26%2334%3Btest.com%26%2334%3B%7D%2C%20nil%7D%2C%5Cn%20%20%7D%2C%5Cn%20%20%7B%5Cn%20%20%20Values%3A%20gomonkey.Params%7Bnil%2C%20errors.New(%26%2334%3Brequest%20err%26%2334%3B)%7D%2C%5Cn%20%20%7D%2C%5Cn%20%20%7B%5Cn%20%20%20Values%3A%20gomonkey.Params%7B%26PersonDetail%7BUsername%3A%20%26%2334%3Bsteven%26%2334%3B%2C%20Email%3A%20%26%2334%3B12345678%40qq.com%26%2334%3B%7D%2C%20nil%7D%2C%5Cn%20%20%7D%2C%5Cn%20%7D%5Cn%20patches%20%3A%3D%20gomonkey.ApplyFuncSeq(getPersonDetailRedis%2C%20outputs)%5Cn%20%2F%2F%20%E6%89%A7%E8%A1%8C%E5%AE%8C%E6%AF%95%E5%90%8E%E9%87%8A%E6%94%BE%E6%A1%A9%E5%BA%8F%E5%88%97%5Cn%20defer%20patches.Reset()%5Cn%5Cn%20for%20_%2C%20tt%20%3A%3D%20range%20tests%20%7B%5Cn%20%20got%2C%20err%20%3A%3D%20GetPersonDetail(tt.args.username)%5Cn%20%20assert.Equal(t%2C%20tt.want%2C%20got)%5Cn%20%20assert.Equal(t%2C%20tt.wantErr%2C%20err%20!%3D%20nil)%5Cn%20%7D%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2244%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%BD%93%E4%BD%BF%E7%94%A8%E6%A1%A9%E5%BA%8F%E5%88%97%E6%97%B6%EF%BC%8C%E8%A6%81%E5%88%86%E6%9E%90%E5%A5%BD%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B%E5%92%8C%E5%BA%8F%E5%88%97%E5%80%BC%E7%9A%84%E5%AF%B9%E5%BA%94%E5%85%B3%E7%B3%BB%EF%BC%8C%E4%BF%9D%E8%AF%81%E6%9C%80%E7%BB%88%E8%A2%AB%E6%B5%8B%E8%AF%95%E7%9A%84%E4%BB%A3%E7%A0%81%E5%9D%97%E9%83%BD%E8%83%BD%E8%A2%AB%E5%AE%8C%E6%95%B4%E8%A6%86%E7%9B%96%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2245%5C%22%3E%3Cspan%20style%3D%5C%22font-size%3A%201.118em%3B%5C%22%3E%3Cstrong%3E%E4%BD%BF%E7%94%A8%20gomock%20%E6%89%93%E6%A1%A9%3C%2Fstrong%3E%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2246%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%9C%80%E5%90%8E%E5%89%A9%E4%B8%8B%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EgetPersonDetailRedis%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%EF%BC%8C%E6%88%91%E4%BB%AC%E5%85%88%E6%9D%A5%E7%9C%8B%E4%B8%80%E4%B8%8B%E8%BF%99%E4%B8%AA%E5%87%BD%E6%95%B0%E7%9A%84%E9%80%BB%E8%BE%91%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3E%2F%2F%20%E9%80%9A%E8%BF%87%20redis%20%E6%8B%89%E5%8F%96%E5%AF%B9%E5%BA%94%E7%94%A8%E6%88%B7%E7%9A%84%E8%B5%84%E6%96%99%E4%BF%A1%E6%81%AF%5Cnfunc%20getPersonDetailRedis(username%20string)%20(*PersonDetail%2C%20error)%20%7B%5Cn%20result%20%3A%3D%20%26PersonDetail%7B%7D%5Cn%5Cn%20client%2C%20err%20%3A%3D%20redis.Dial(%26%2334%3Btcp%26%2334%3B%2C%20%26%2334%3B%3A6379%26%2334%3B)%5Cn%20defer%20client.Close()%5Cn%20data%2C%20err%20%3A%3D%20redis.Bytes(client.Do(%26%2334%3BGET%26%2334%3B%2C%20username))%5Cn%5Cn%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20return%20nil%2C%20err%5Cn%20%7D%5Cn%5Cn%20err%20%3D%20json.Unmarshal(data%2C%20result)%5Cn%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20return%20nil%2C%20err%5Cn%20%7D%5Cn%5Cn%20return%20result%2C%20nil%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2248%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EgetPersonDetailRedis%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E7%9A%84%E6%A0%B8%E5%BF%83%E5%9C%A8%E4%BA%8E%E7%94%9F%E6%88%90%E4%BA%86%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Eclient%3C%2Fspan%3E%3C%2Fspan%3E%20%E8%B0%83%E7%94%A8%E4%BA%86%E5%AE%83%E7%9A%84%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EDo%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%96%B9%E6%B3%95%EF%BC%8C%E9%80%9A%E8%BF%87%E5%88%86%E6%9E%90%E5%BE%97%E7%9F%A5%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Eclient%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%AE%9E%E9%99%85%E4%B8%8A%E6%98%AF%E4%B8%80%E4%B8%AA%E7%AC%A6%E5%90%88%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EConn%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%8E%A5%E5%8F%A3%E7%9A%84%E7%BB%93%E6%9E%84%E4%BD%93%E3%80%82%E5%A6%82%E6%9E%9C%E6%88%91%E4%BB%AC%E4%BD%BF%E7%94%A8%20gomonkey%20%E6%9D%A5%E8%BF%9B%E8%A1%8C%E6%89%93%E6%A1%A9%EF%BC%8C%E9%9C%80%E8%A6%81%E5%85%88%E5%A3%B0%E6%98%8E%E4%B8%80%E4%B8%AA%E7%BB%93%E6%9E%84%E4%BD%93%E5%B9%B6%E5%AE%9E%E7%8E%B0%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EClient%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%8E%A5%E5%8F%A3%E6%8B%A5%E6%9C%89%E7%9A%84%E6%96%B9%E6%B3%95%EF%BC%8C%E4%B9%8B%E5%90%8E%E6%89%8D%E8%83%BD%E4%BD%BF%E7%94%A8%20gomonkey%20%E7%BB%99%E5%87%BD%E6%95%B0%E6%89%93%E6%A1%A9%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3E%2F%2F%20redis%20%E5%8C%85%E4%B8%AD%E5%85%B3%E4%BA%8E%20Conn%20%E7%9A%84%E5%AE%9A%E4%B9%89%5Cn%2F%2F%20Conn%20represents%20a%20connection%20to%20a%20Redis%20server.%5Cntype%20Conn%20interface%20%7B%5Cn%20%2F%2F%20Close%20closes%20the%20connection.%5Cn%20Close()%20error%5Cn%5Cn%20%2F%2F%20Err%20returns%20a%20non-nil%20value%20when%20the%20connection%20is%20not%20usable.%5Cn%20Err()%20error%5Cn%5Cn%20%2F%2F%20Do%20sends%20a%20command%20to%20the%20server%20and%20returns%20the%20received%20reply.%5Cn%20Do(commandName%20string%2C%20args%20...interface%7B%7D)%20(reply%20interface%7B%7D%2C%20err%20error)%5Cn%5Cn%20%2F%2F%20Send%20writes%20the%20command%20to%20the%20client%26%2339%3Bs%20output%20buffer.%5Cn%20Send(commandName%20string%2C%20args%20...interface%7B%7D)%20error%5Cn%5Cn%20%2F%2F%20Flush%20flushes%20the%20output%20buffer%20to%20the%20Redis%20server.%5Cn%20Flush()%20error%5Cn%5Cn%20%2F%2F%20Receive%20receives%20a%20single%20reply%20from%20the%20Redis%20server%5Cn%20Receive()%20(reply%20interface%7B%7D%2C%20err%20error)%5Cn%7D%5Cn%5Cn%2F%2F%20%E5%AE%9E%E7%8E%B0%E6%8E%A5%E5%8F%A3%5Cntype%20Client%20struct%20%7B%7D%5Cnfunc%20(c%20*Client)%20Close()%20error%20%7B%5Cn%20%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Err()%20error%20%7B%5Cn%20%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Do(commandName%20string%2C%20args%20...interface%7B%7D)%20(interface%7B%7D%2C%20error)%20%7B%5Cn%20%20return%20nil%2C%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Send(commandName%20string%2C%20args%20...interface%7B%7D)%20error%20%7B%5Cn%20%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Flush()%20error%20%7B%5Cn%20%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Receive()%20(interface%7B%7D%2C%20error)%20%7B%5Cn%20%20return%20nil%2C%20nil%5Cn%7D%5Cn%5Cn%2F%2F%20%E5%AE%9E%E7%8E%B0%E6%8E%A5%E5%8F%A3%5Cntype%20Client%20struct%20%7B%7D%5Cnfunc%20(c%20*Client)%20Close()%20error%20%7B%5Cn%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Err()%20error%20%7B%5Cn%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Do(commandName%20string%2C%20args%20...interface%7B%7D)%20(interface%7B%7D%2C%20error)%20%7B%5Cn%20return%20nil%2C%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Send(commandName%20string%2C%20args%20...interface%7B%7D)%20error%20%7B%5Cn%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Flush()%20error%20%7B%5Cn%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Receive()%20(interface%7B%7D%2C%20error)%20%7B%5Cn%20return%20nil%2C%20nil%5Cn%7D%5Cn%2F%2F%20%E8%BF%9B%E8%A1%8C%E6%B5%8B%E8%AF%95%5Cnfunc%20test()%20%7B%5Cn%20c%20%3A%3D%20%26Client%7B%7D%5Cn%20gomonkey.ApplyFunc(redis.Dial%2C%20func(_%20string%2C%20_%20string%2C%20_%20...redis.DialOption)%20(redis.Conn%2C%20error)%20%7B%5Cn%20%20return%20c%2C%20nil%5Cn%20%7D)%5Cn%20gomonkey.ApplyMethod(reflect.TypeOf(c)%2C%20%26%2334%3BDo%26%2334%3B%2C%20func(commandName%20string%2C%20args%20...interface%7B%7D)%20(interface%7B%7D%2C%20error)%20%7B%5Cn%20%20var%20result%20interface%7B%7D%5Cn%20%20return%20result%2C%20nil%5Cn%20%7D)%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2250%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%8F%AF%E8%A7%81%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%8E%A5%E5%8F%A3%E5%AE%9E%E7%8E%B0%E7%9A%84%E6%96%B9%E6%B3%95%E6%9B%B4%E5%A4%9A%EF%BC%8C%E9%82%A3%E4%B9%88%E6%89%93%E6%A1%A9%E9%9C%80%E8%A6%81%E6%89%8B%E5%86%99%E7%9A%84%E4%BB%A3%E7%A0%81%E4%BC%9A%E6%9B%B4%E5%A4%9A%E3%80%82%E5%9B%A0%E6%AD%A4%E8%BF%99%E9%87%8C%E9%9C%80%E8%A6%81%E4%B8%80%E7%A7%8D%E8%83%BD%E8%87%AA%E5%8A%A8%E6%A0%B9%E6%8D%AE%E5%8E%9F%E6%8E%A5%E5%8F%A3%E7%9A%84%E5%AE%9A%E4%B9%89%E7%94%9F%E6%88%90%E6%8E%A5%E5%8F%A3%E7%9A%84%20mock%20%E4%BB%A3%E7%A0%81%E4%BB%A5%E5%8F%8A%E6%9B%B4%E6%96%B9%E4%BE%BF%E7%9A%84%E6%8E%A5%E5%8F%A3%20mock%20%E6%96%B9%E5%BC%8F%E3%80%82%E4%BA%8E%E6%98%AF%E8%BF%99%E9%87%8C%E6%88%91%E4%BB%AC%E4%BD%BF%E7%94%A8%20gomock%20%E6%9D%A5%E8%A7%A3%E5%86%B3%E8%BF%99%E4%B8%AA%E9%97%AE%E9%A2%98%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2251%5C%22%3E%3Cstrong%3E%E6%9C%AC%E5%9C%B0%E5%AE%89%E8%A3%85%20gomock%3C%2Fstrong%3E%3C%2Fp%3E%3Cpre%3E%3Ccode%3E%23%20%E6%89%93%E5%BC%80%E7%BB%88%E7%AB%AF%E5%90%8E%E4%BE%9D%E6%AC%A1%E6%89%A7%E8%A1%8C%5Cngo%20get%20-u%20github.com%2Fgolang%2Fmock%2Fgomock%5Cngo%20install%20github.com%2Fgolang%2Fmock%2Fmockgen%5Cn%23%20%E5%A4%87%E6%B3%A8%E8%AF%B4%E6%98%8E%EF%BC%8C%E5%BE%88%E9%87%8D%E8%A6%81%EF%BC%81%EF%BC%81%EF%BC%81%5Cn%23%20%E5%AE%89%E8%A3%85%E5%AE%8C%E6%88%90%E4%B9%8B%E5%90%8E%EF%BC%8C%E6%89%A7%E8%A1%8C%20mockgen%20%E7%9C%8B%E5%91%BD%E4%BB%A4%E6%98%AF%E5%90%A6%E7%94%9F%E6%95%88%20%23%20%E5%A6%82%E6%9E%9C%E6%98%BE%E7%A4%BA%E5%91%BD%E4%BB%A4%E6%97%A0%E6%95%88%EF%BC%8C%E8%AF%B7%E6%89%BE%E5%88%B0%E6%9C%AC%E6%9C%BA%E7%9A%84%20GOPATH%20%E5%AE%89%E8%A3%85%E7%9B%AE%E5%BD%95%E4%B8%8B%E7%9A%84%20bin%20%E6%96%87%E4%BB%B6%E5%A4%B9%E6%98%AF%E5%90%A6%E6%9C%89%20mockgen%20%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%96%87%E4%BB%B6%5Cn%23%20GOPATH%20%E5%8F%AF%E4%BB%A5%E6%89%A7%E8%A1%8C%20go%20env%20%E5%91%BD%E4%BB%A4%E6%89%BE%E5%88%B0%5Cn%23%20%E5%A6%82%E6%9E%9C%E5%91%BD%E4%BB%A4%E6%97%A0%E6%95%88%E4%BD%86%E6%98%AF%20GOPATH%20%E8%B7%AF%E5%BE%84%E4%B8%8B%E7%9A%84%20bin%20%E6%96%87%E4%BB%B6%E5%A4%B9%E4%B8%AD%E5%AD%98%E5%9C%A8%20mockgen%EF%BC%8C%E8%AF%B7%E5%B0%86%20GOPATH%20%E4%B8%8B%20bin%20%E6%96%87%E4%BB%B6%E5%A4%B9%E7%9A%84%E7%BB%9D%E5%AF%B9%E8%B7%AF%E5%BE%84%E6%B7%BB%E5%8A%A0%E5%88%B0%E5%85%A8%E5%B1%80%20PATH%20%E4%B8%AD%5Cn%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2253%5C%22%3E%3Cstrong%3E%E7%94%9F%E6%88%90%20gomock%20%E6%A1%A9%E4%BB%A3%E7%A0%81%3C%2Fstrong%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2254%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AE%89%E8%A3%85%E5%AE%8C%E6%AF%95%E5%90%8E%EF%BC%8C%E6%89%BE%E5%88%B0%E8%A6%81%E8%BF%9B%E8%A1%8C%E6%89%93%E6%A1%A9%E7%9A%84%E6%8E%A5%E5%8F%A3%EF%BC%8C%E8%BF%99%E9%87%8C%E6%98%AF%20github.com%2Fgomodule%2Fredigo%2Fredis%20%E5%8C%85%E9%87%8C%E9%9D%A2%E7%9A%84%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EConn%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%8E%A5%E5%8F%A3%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2255%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9C%A8%E5%BD%93%E5%89%8D%E4%BB%A3%E7%A0%81%E7%9B%AE%E5%BD%95%E4%B8%8B%E6%89%A7%E8%A1%8C%E4%BB%A5%E4%B8%8B%E6%8C%87%E4%BB%A4%EF%BC%8C%E8%BF%99%E9%87%8C%E6%88%91%E4%BB%AC%E5%8F%AA%E5%AF%B9%E6%9F%90%E4%B8%AA%E7%89%B9%E5%AE%9A%E7%9A%84%E6%8E%A5%E5%8F%A3%E7%94%9F%E6%88%90%20mock%20%E4%BB%A3%E7%A0%81%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cpre%3E%3Ccode%3Emockgen%20-destination%3Dmock_redis.go%20-package%3Dunit%20github.com%2Fgomodule%2Fredigo%2Fredis%20Conn%5Cn%23%20%E6%9B%B4%E5%A4%9A%E6%8C%87%E4%BB%A4%E5%8F%82%E8%80%83%EF%BC%9Ahttps%3A%2F%2Fgithub.com%2Fgolang%2Fmock%23flags%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2257%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%94%9F%E6%88%90%E7%9A%84%E4%BB%A3%E7%A0%81%E5%8F%82%E8%80%83%20mock_redis.go%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2258%5C%22%3E%3Cstrong%3E%E5%AE%8C%E5%96%84%20gomock%20%E7%9B%B8%E5%85%B3%E9%80%BB%E8%BE%91%3C%2Fstrong%3E%3C%2Fp%3E%3Cpre%3E%3Ccode%3Efunc%20Test_getPersonDetailRedis(t%20*testing.T)%20%7B%5Cn%20tests%20%3A%3D%20%5B%5Dstruct%20%7B%5Cn%20%20name%20%20%20%20string%5Cn%20%20want%20%20%20%20*PersonDetail%5Cn%20%20wantErr%20bool%5Cn%20%7D%7B%5Cn%20%20%7Bname%3A%20%26%2334%3Bredis.Do%20err%26%2334%3B%2C%20want%3A%20nil%2C%20wantErr%3A%20true%7D%2C%5Cn%20%20%7Bname%3A%20%26%2334%3Bjson.Unmarshal%20err%26%2334%3B%2C%20want%3A%20nil%2C%20wantErr%3A%20true%7D%2C%5Cn%20%20%7Bname%3A%20%26%2334%3Bsuccess%26%2334%3B%2C%20want%3A%20%26PersonDetail%7B%5Cn%20%20%20Username%3A%20%26%2334%3Bsteven%26%2334%3B%2C%5Cn%20%20%20Email%3A%20%20%20%20%26%2334%3B1234567%40qq.com%26%2334%3B%2C%5Cn%20%20%7D%2C%20wantErr%3A%20false%7D%2C%5Cn%20%7D%5Cn%20ctrl%20%3A%3D%20gomock.NewController(t)%5Cn%20defer%20ctrl.Finish()%5Cn%5Cn%20%2F%2F%201.%20%E7%94%9F%E6%88%90%E7%AC%A6%E5%90%88%20redis.Conn%20%E6%8E%A5%E5%8F%A3%E7%9A%84%20mockConn%5Cn%20mockConn%20%3A%3D%20NewMockConn(ctrl)%5Cn%5Cn%20%2F%2F%202.%20%E7%BB%99%E6%8E%A5%E5%8F%A3%E6%89%93%E6%A1%A9%E5%BA%8F%E5%88%97%5Cn%20gomock.InOrder(%5Cn%20%20mockConn.EXPECT().Do(%26%2334%3BGET%26%2334%3B%2C%20gomock.Any()).Return(%26%2334%3B%26%2334%3B%2C%20errors.New(%26%2334%3Bredis.Do%20err%26%2334%3B))%2C%5Cn%20%20mockConn.EXPECT().Close().Return(nil)%2C%5Cn%20%20mockConn.EXPECT().Do(%26%2334%3BGET%26%2334%3B%2C%20gomock.Any()).Return(%26%2334%3B123%26%2334%3B%2C%20nil)%2C%5Cn%20%20mockConn.EXPECT().Close().Return(nil)%2C%5Cn%20%20mockConn.EXPECT().Do(%26%2334%3BGET%26%2334%3B%2C%20gomock.Any()).Return(%5B%5Dbyte(%60%7B%26%2334%3Busername%26%2334%3B%3A%20%26%2334%3Bsteven%26%2334%3B%2C%20%26%2334%3Bemail%26%2334%3B%3A%20%26%2334%3B1234567%40qq.com%26%2334%3B%7D%60)%2C%20nil)%2C%5Cn%20%20mockConn.EXPECT().Close().Return(nil)%2C%5Cn%20)%5Cn%5Cn%20%2F%2F%203.%20%E7%BB%99%20redis.Dail%20%E5%87%BD%E6%95%B0%E6%89%93%E6%A1%A9%5Cn%20outputs%20%3A%3D%20%5B%5Dgomonkey.OutputCell%7B%5Cn%20%20%7B%5Cn%20%20%20Values%3A%20gomonkey.Params%7BmockConn%2C%20nil%7D%2C%5Cn%20%20%20Times%3A%20%203%2C%20%2F%2F%203%20%E4%B8%AA%E7%94%A8%E4%BE%8B%5Cn%20%20%7D%2C%5Cn%20%7D%5Cn%20patches%20%3A%3D%20gomonkey.ApplyFuncSeq(redis.Dial%2C%20outputs)%5Cn%20%2F%2F%20%E6%89%A7%E8%A1%8C%E5%AE%8C%E6%AF%95%E4%B9%8B%E5%90%8E%E9%87%8A%E6%94%BE%E6%A1%A9%E5%BA%8F%E5%88%97%5Cn%20defer%20patches.Reset()%5Cn%5Cn%20%2F%2F%204.%20%E6%96%AD%E8%A8%80%5Cn%20for%20_%2C%20tt%20%3A%3D%20range%20tests%20%7B%5Cn%20%20actual%2C%20err%20%3A%3D%20getPersonDetailRedis(tt.name)%5Cn%20%20%2F%2F%20%E6%B3%A8%E6%84%8F%EF%BC%8Cequal%20%E5%87%BD%E6%95%B0%E8%83%BD%E5%A4%9F%E5%AF%B9%E7%BB%93%E6%9E%84%E4%BD%93%E8%BF%9B%E8%A1%8C%20deap%20diff%5Cn%20%20assert.Equal(t%2C%20tt.want%2C%20actual)%5Cn%20%20assert.Equal(t%2C%20tt.wantErr%2C%20err%20!%3D%20nil)%5Cn%20%7D%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2260%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%BB%8E%E4%B8%8A%E9%9D%A2%E5%8F%AF%E4%BB%A5%E7%9C%8B%E5%88%B0%EF%BC%8C%E7%BB%99%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EgetPersonDetailRedis%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E5%81%9A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%BB%E8%A6%81%E5%81%9A%E4%BA%86%E5%9B%9B%E4%BB%B6%E4%BA%8B%E6%83%85%EF%BC%9A%3C%2Fp%3E%3Cul%3E%3Cli%20data-track%3D%5C%2261%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%94%9F%E6%88%90%E7%AC%A6%E5%90%88%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Eredis.Conn%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%8E%A5%E5%8F%A3%E7%9A%84%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EmockConn%3C%2Fspan%3E%3C%2Fspan%3E%3C%2Fli%3E%3Cli%20data-track%3D%5C%2262%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%BB%99%E6%8E%A5%E5%8F%A3%E6%89%93%E6%A1%A9%E5%BA%8F%E5%88%97%3C%2Fspan%3E%3C%2Fli%3E%3Cli%20data-track%3D%5C%2263%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%BB%99%E5%87%BD%E6%95%B0%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Eredis.Dial%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%89%93%E6%A1%A9%3C%2Fli%3E%3Cli%20data-track%3D%5C%2264%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%96%AD%E8%A8%80%3C%2Fspan%3E%3C%2Fli%3E%3C%2Ful%3E%3Cp%20data-track%3D%5C%2265%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%BF%99%E9%87%8C%E9%9D%A2%E5%90%8C%E6%97%B6%E4%BD%BF%E7%94%A8%E4%BA%86%20gomock%E3%80%81gomonkey%20%E5%92%8C%20testify%20%E4%B8%89%E4%B8%AA%E5%8C%85%E4%BD%9C%E4%B8%BA%E5%8E%8B%E6%B5%8B%E5%B7%A5%E5%85%B7%EF%BC%8C%E6%97%A5%E5%B8%B8%E4%BD%BF%E7%94%A8%E4%B8%AD%EF%BC%8C%E7%94%B1%E4%BA%8E%E5%A4%8D%E6%9D%82%E7%9A%84%E8%B0%83%E7%94%A8%E9%80%BB%E8%BE%91%E5%B8%A6%E6%9D%A5%E7%B9%81%E6%9D%82%E7%9A%84%E5%8D%95%E6%B5%8B%EF%BC%8C%E4%B9%9F%E6%97%A0%E5%A4%96%E4%B9%8E%E4%BD%BF%E7%94%A8%E8%BF%99%E4%B8%89%E4%B8%AA%E5%8C%85%E5%8D%8F%E5%90%8C%E5%AE%8C%E6%88%90%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2266%5C%22%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233D89FF%3B%20--tt-darkmode-color%3A%20%233D89FF%3B%5C%22%3E%E6%9F%A5%E7%9C%8B%E5%8D%95%E6%B5%8B%E6%8A%A5%E5%91%8A%3C%2Fspan%3E%3C%2Fstrong%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2267%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%BC%96%E5%86%99%E5%AE%8C%E6%AF%95%E4%B9%8B%E5%90%8E%EF%BC%8C%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E8%B0%83%E7%94%A8%E7%9B%B8%E5%85%B3%E7%9A%84%E6%8C%87%E4%BB%A4%E6%9D%A5%E6%9F%A5%E7%9C%8B%E8%A6%86%E7%9B%96%E8%8C%83%E5%9B%B4%EF%BC%8C%E5%B8%AE%E5%8A%A9%E6%88%91%E4%BB%AC%E6%9F%A5%E7%9C%8B%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E6%98%AF%E5%90%A6%E5%B7%B2%E7%BB%8F%E5%AE%8C%E5%85%A8%E8%A6%86%E7%9B%96%E9%80%BB%E8%BE%91%E4%BB%A3%E7%A0%81%EF%BC%8C%E4%BB%A5%E4%BE%BF%E6%88%91%E4%BB%AC%E5%8F%8A%E6%97%B6%E8%B0%83%E6%95%B4%E5%8D%95%E6%B5%8B%E9%80%BB%E8%BE%91%E5%92%8C%E7%94%A8%E4%BE%8B%E3%80%82%E6%9C%AC%E6%96%87%E4%B8%AD%E5%AE%8C%E6%95%B4%E7%9A%84%E5%8D%95%E6%B5%8B%E4%BB%A3%E7%A0%81%E5%8F%82%E8%80%83%EF%BC%9Aget_person_detail_test.go%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2268%5C%22%3E%3Cstrong%3E%E4%BD%BF%E7%94%A8%20go%20test%20%E6%8C%87%E4%BB%A4%3C%2Fstrong%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2269%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E9%BB%98%E8%AE%A4%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E6%88%91%E4%BB%AC%E5%9C%A8%E5%BD%93%E5%89%8D%E4%BB%A3%E7%A0%81%E7%9B%AE%E5%BD%95%E4%B8%8B%E6%89%A7%E8%A1%8C%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ego%20test%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%8C%87%E4%BB%A4%EF%BC%8C%E4%BC%9A%E8%87%AA%E5%8A%A8%E7%9A%84%E6%89%A7%E8%A1%8C%E5%BD%93%E5%89%8D%E7%9B%AE%E5%BD%95%E4%B8%8B%E9%9D%A2%E5%B8%A6%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E_test.go%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%90%8E%E7%BC%80%E7%9A%84%E6%96%87%E4%BB%B6%E8%BF%9B%E8%A1%8C%E6%B5%8B%E8%AF%95%E3%80%82%E5%A6%82%E8%8B%A5%E6%83%B3%E5%B1%95%E7%A4%BA%E5%85%B7%E4%BD%93%E7%9A%84%E6%B5%8B%E8%AF%95%E5%87%BD%E6%95%B0%E4%BB%A5%E5%8F%8A%E8%A6%86%E7%9B%96%E7%8E%87%EF%BC%8C%E5%8F%AF%E4%BB%A5%E6%B7%BB%E5%8A%A0%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E-v%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%92%8C%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E-cover%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%8F%82%E6%95%B0%EF%BC%8C%E5%A6%82%E4%B8%8B%E6%89%80%E7%A4%BA%EF%BC%9A%3C%2Fp%3E%3Cpre%3E%3Ccode%3E%E2%98%81%EF%B8%8F%20%20go_unit_test%20%5Bmaster%5D%20%20%20go%20test%20-v%20-cover%5Cn%3D%3D%3D%20RUN%20%20%20TestGetPersonDetail%5Cn---%20PASS%3A%20TestGetPersonDetail%20(0.00s)%5Cn%3D%3D%3D%20RUN%20%20%20Test_checkEmail%5Cn---%20PASS%3A%20Test_checkEmail%20(0.00s)%5Cn%3D%3D%3D%20RUN%20%20%20Test_checkUsername%5Cn---%20PASS%3A%20Test_checkUsername%20(0.00s)%5Cn%3D%3D%3D%20RUN%20%20%20Test_getPersonDetailRedis%5Cn---%20PASS%3A%20Test_getPersonDetailRedis%20(0.00s)%5CnPASS%5Cncoverage%3A%2060.8%25%20of%20statements%5Cnok%20%20%20%20%20%20unit%20%20%20%200.131s%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2271%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%A6%82%E6%9E%9C%E6%83%B3%E6%8C%87%E5%AE%9A%E6%B5%8B%E8%AF%95%E6%9F%90%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%9C%A8%E6%8C%87%E4%BB%A4%E5%90%8E%E9%9D%A2%E6%B7%BB%E5%8A%A0%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E-run%20%24%7Btest%E6%96%87%E4%BB%B6%E5%86%85%E5%87%BD%E6%95%B0%E5%90%8D%7D%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%9D%A5%E6%8C%87%E5%AE%9A%E6%89%A7%E8%A1%8C%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3E%E2%98%81%EF%B8%8F%20%20go_unit_test%20%5Bmaster%5D%20%20%20go%20test%20-cover%20-v%20%20-run%20Test_getPersonDetailRedis%5Cn%3D%3D%3D%20RUN%20%20%20Test_getPersonDetailRedis%5Cn---%20PASS%3A%20Test_getPersonDetailRedis%20(0.00s)%5CnPASS%5Cncoverage%3A%2041.9%25%20of%20statements%5Cnok%20%20%20%20%20%20unit%20%20%20%200.369s%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2273%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9C%A8%E6%89%A7%E8%A1%8C%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ego%20test%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%91%BD%E4%BB%A4%E6%97%B6%EF%BC%8C%E9%9C%80%E8%A6%81%E5%8A%A0%E4%B8%8A%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E-gcflags%3Dall%3D-l%3C%2Fspan%3E%3C%2Fspan%3E%20%E9%98%B2%E6%AD%A2%E7%BC%96%E8%AF%91%E5%99%A8%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E5%AF%BC%E8%87%B4%E5%8D%95%E6%B5%8B%E5%87%BA%E7%8E%B0%E9%97%AE%E9%A2%98%EF%BC%8C%E8%BF%99%E8%B7%9F%E6%89%93%E6%A1%A9%E4%BB%A3%E7%A0%81%E5%AD%98%E5%9C%A8%E5%AF%86%E5%88%87%E7%9A%84%E5%85%B3%E7%B3%BB%EF%BC%8C%E5%90%8E%E9%9D%A2%E6%88%91%E4%BB%AC%E4%BC%9A%E8%AF%A6%E7%BB%86%E7%9A%84%E4%BB%8B%E7%BB%8D%E8%BF%99%E4%B8%80%E7%82%B9%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2274%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9B%A0%E6%AD%A4%EF%BC%8C%E4%B8%80%E4%B8%AA%E5%AE%8C%E6%95%B4%E7%9A%84%E5%8D%95%E6%B5%8B%E6%8C%87%E4%BB%A4%E5%8F%AF%E4%BB%A5%E6%98%AF%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ego%20test%20-v%20-cover%20-gcflags%3Dall%3D-l%20-coverprofile%3Dcoverage.out%3C%2Fspan%3E%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2275%5C%22%3E%3Cstrong%3E%E7%94%9F%E6%88%90%E8%A6%86%E7%9B%96%E6%8A%A5%E5%91%8A%3C%2Fstrong%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2276%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%9C%80%E5%90%8E%EF%BC%8C%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E6%89%A7%E8%A1%8C%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ego%20tool%20cover%20-html%3Dcoverage.out%3C%2Fspan%3E%3C%2Fspan%3E%20%EF%BC%8C%E6%9F%A5%E7%9C%8B%E4%BB%A3%E7%A0%81%E7%9A%84%E8%A6%86%E7%9B%96%E6%83%85%E5%86%B5%EF%BC%8C%E4%BD%BF%E7%94%A8%E5%89%8D%E8%AF%B7%E5%85%88%E5%AE%89%E8%A3%85%E5%A5%BD%20go%20tool%20%E5%B7%A5%E5%85%B7%E3%80%82%3C%2Fp%3E%3Cdiv%20class%3D%5C%22pgc-img%5C%22%3E%3Cimg%20src%3D%5C%22https%3A%2F%2Fp3-sign.toutiaoimg.com%2Ftos-cn-i-qvj2lq49k0%2Fe108da3ebb3741d7af7665d5a59ff21c~tplv-tt-origin-web%3Agif.jpeg%3F_iz%3D58558%26from%3Darticle.pc_detail%26lk3s%3D953192f4%26x-expires%3D1734609857%26x-signature%3DVvb2b50Q84K4UtpZubecV0HS6HQ%253D%5C%22%20img_width%3D%5C%22876%5C%22%20img_height%3D%5C%22979%5C%22%20image_type%3D%5C%221%5C%22%20mime_type%3D%5C%22image%2Fjpeg%5C%22%20web_uri%3D%5C%22tos-cn-i-qvj2lq49k0%2Fe108da3ebb3741d7af7665d5a59ff21c%5C%22%3E%3Cp%20class%3D%5C%22pgc-img-caption%5C%22%3E%3C%2Fp%3E%3C%2Fdiv%3E%3Cp%20data-track%3D%5C%2278%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%8F%AF%E4%BB%A5%E7%9C%8B%E5%88%B0%E5%BE%85%E6%B5%8B%E7%9A%84%E4%BB%A3%E7%A0%81%E8%A6%86%E7%9B%96%E7%8E%87%E8%BE%BE%E5%88%B0%20100%25%20%E4%BA%86%EF%BC%8C%E5%AE%8C%E6%95%B4%E7%9A%84%E4%BB%A3%E7%A0%81%E4%BB%93%E5%BA%93%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%EF%BC%9Ahttps%3A%2F%2Fgithub.com%2Fxunan007%2Fgo_unit_test%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2279%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%85%B3%E4%BA%8E%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ego%20test%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%9B%B4%E5%A4%9A%E7%9A%84%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%EF%BC%9A%3C%2Fp%3E%3Cp%20data-track%3D%5C%2280%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3Ehttps%3A%2F%2Fgolang.org%2Fpkg%2Fcmd%2Fgo%2Finternal%2Ftest%2F%3C%2Fspan%3E%3C%2Fp%3E%3Ch1%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2281%5C%22%3E%E6%80%9D%E8%80%83%3C%2Fh1%3E%3Cp%20data-track%3D%5C%2282%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%B8%8A%E9%9D%A2%E6%88%91%E4%BB%AC%E5%B7%B2%E7%BB%8F%E8%AF%A6%E7%BB%86%E7%9A%84%E4%BB%8B%E7%BB%8D%E4%BA%86%E5%A6%82%E4%BD%95%E5%AF%B9%20go%20%E4%BB%A3%E7%A0%81%E8%BF%9B%E8%A1%8C%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E3%80%82%E4%B8%8B%E9%9D%A2%E6%8E%A2%E8%AE%A8%E4%B8%A4%E4%B8%AA%E9%97%AE%E9%A2%98%EF%BC%8C%E5%B8%AE%E5%8A%A9%E6%88%91%E4%BB%AC%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3%20go%20%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E8%BF%87%E7%A8%8B%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2283%5C%22%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233D89FF%3B%20--tt-darkmode-color%3A%20%233D89FF%3B%5C%22%3EQ1%EF%BC%9A%E6%A1%A9%E4%BB%A3%E7%A0%81%E5%9C%A8%E5%8D%95%E6%B5%8B%E4%B8%AD%E6%98%AF%E5%A6%82%E4%BD%95%E6%89%A7%E8%A1%8C%E7%9A%84%3C%2Fspan%3E%3C%2Fstrong%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2284%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9C%A8%E4%B8%8A%E9%9D%A2%E7%9A%84%E6%A1%88%E4%BE%8B%E4%B8%AD%EF%BC%8C%E9%92%88%E5%AF%B9%20interface%20%E6%88%91%E4%BB%AC%E9%80%9A%E8%BF%87%20gomock%20%E6%9D%A5%E5%B8%AE%E6%88%91%E4%BB%AC%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90%E7%AC%A6%E5%90%88%E6%8E%A5%E5%8F%A3%E7%9A%84%E7%B1%BB%E5%90%8E%EF%BC%8C%E5%8F%AA%E9%9C%80%E8%A6%81%E9%80%9A%E8%BF%87%20gomock%20%E7%BA%A6%E5%AE%9A%E7%9A%84%20API%20%E5%B0%B1%E8%83%BD%E5%A4%9F%E5%AF%B9%20interface%20%E4%B8%AD%E7%9A%84%E5%87%BD%E6%95%B0%E6%8C%89%E6%9C%9F%E6%9C%9B%E5%92%8C%E9%9C%80%E8%A6%81%E6%9D%A5%E6%A8%A1%E6%8B%9F%EF%BC%8C%E8%BF%99%E4%B8%AA%E5%BE%88%E5%A5%BD%E7%90%86%E8%A7%A3%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2285%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AF%B9%E4%BA%8E%E5%87%BD%E6%95%B0%E4%BB%A5%E5%8F%8A%E6%96%B9%E6%B3%95%E7%9A%84%20mock%EF%BC%8C%E7%94%B1%E4%BA%8E%E6%9C%AC%E8%BA%AB%E4%BB%A3%E7%A0%81%E9%80%BB%E8%BE%91%E5%B7%B2%E7%BB%8F%E5%A3%B0%E6%98%8E%E5%A5%BD%EF%BC%88go%20%E6%98%AF%E9%9D%99%E6%80%81%E5%BC%BA%E7%B1%BB%E5%9E%8B%E8%AF%AD%E8%A8%80%EF%BC%89%EF%BC%8C%E6%88%91%E4%BB%AC%E5%BE%88%E9%9A%BE%E9%80%9A%E8%BF%87%E7%BC%96%E7%A0%81%E7%9A%84%E6%96%B9%E5%BC%8F%E5%B0%86%E5%85%B6%20mock%20%E6%8E%89%EF%BC%8C%E8%BF%99%E5%AF%B9%E6%88%91%E4%BB%AC%E5%81%9A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E6%8F%90%E4%BE%9B%E4%BA%86%E5%BE%88%E5%A4%A7%E7%9A%84%E6%8C%91%E6%88%98%E3%80%82%E5%AE%9E%E9%99%85%E4%B8%8A%20gomonkey%20%E6%8F%90%E4%BE%9B%E4%BA%86%E8%AE%A9%E6%88%91%E4%BB%AC%E5%9C%A8%E8%BF%90%E8%A1%8C%E6%97%B6%E6%9B%BF%E6%8D%A2%E5%8E%9F%E5%87%BD%E6%95%B0%2F%E6%96%B9%E6%B3%95%E7%9A%84%E8%83%BD%E5%8A%9B%E3%80%82%E8%99%BD%E7%84%B6%E8%AF%B4%E6%88%91%E4%BB%AC%E5%9C%A8%E8%AF%AD%E8%A8%80%E5%B1%82%E9%9D%A2%E5%BE%88%E9%9A%BE%E5%8E%BB%E6%9B%BF%E6%8D%A2%E8%BF%90%E8%A1%8C%E4%B8%AD%E7%9A%84%E5%87%BD%E6%95%B0%E4%BD%93%EF%BC%8C%E4%BD%86%E6%98%AF%E6%9C%AC%E8%BA%AB%E4%BB%A3%E7%A0%81%E6%9C%80%E7%BB%88%E9%83%BD%E4%BC%9A%E8%BD%AC%E6%8D%A2%E6%88%90%E6%9C%BA%E5%99%A8%E5%8F%AF%E4%BB%A5%E7%90%86%E8%A7%A3%E7%9A%84%E6%B1%87%E7%BC%96%E6%8C%87%E4%BB%A4%EF%BC%8C%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E5%88%9B%E5%BB%BA%E6%8C%87%E4%BB%A4%E6%9D%A5%E6%94%B9%E5%86%99%E5%87%BD%E6%95%B0%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2286%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9C%A8%20gomonkey%20%E6%89%93%E6%A1%A9%E7%9A%84%E8%BF%87%E7%A8%8B%E4%B8%AD%EF%BC%8C%E5%85%B6%E6%A0%B8%E5%BF%83%E5%87%BD%E6%95%B0%E5%85%B6%E5%AE%9E%E6%98%AF%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EApplyCore%3C%2Fspan%3E%3C%2Fspan%3E%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3Efunc%20(this%20*Patches)%20ApplyCore(target%2C%20double%20reflect.Value)%20*Patches%20%7B%5Cn%20this.check(target%2C%20double)%5Cn%20if%20_%2C%20ok%20%3A%3D%20this.originals%5Btarget%5D%3B%20ok%20%7B%5Cn%20%20panic(%26%2334%3Bpatch%20has%20been%20existed%26%2334%3B)%5Cn%20%7D%5Cn%5Cn%20this.valueHolders%5Bdouble%5D%20%3D%20double%5Cn%20original%20%3A%3D%20replace(*(*uintptr)(getPointer(target))%2C%20uintptr(getPointer(double)))%5Cn%20this.originals%5Btarget%5D%20%3D%20original%5Cn%20return%20this%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2288%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%B8%8D%E7%AE%A1%E6%98%AF%E5%AF%B9%E5%87%BD%E6%95%B0%E6%89%93%E6%A1%A9%E8%BF%98%E6%98%AF%E5%AF%B9%E6%96%B9%E6%B3%95%E6%89%93%E6%A1%A9%EF%BC%8C%E5%AE%9E%E9%99%85%E4%B8%8A%E6%9C%80%E5%90%8E%E9%83%BD%E4%BC%9A%E8%B0%83%E7%94%A8%E8%BF%99%E4%B8%AA%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EApplyCore%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2289%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9C%A8%E7%AC%AC%208%20%E8%A1%8C%E7%9A%84%E4%BD%8D%E7%BD%AE%EF%BC%8C%E8%8E%B7%E5%8F%96%E5%88%B0%E4%BC%A0%E5%85%A5%E7%9A%84%E5%8E%9F%E5%A7%8B%E5%87%BD%E6%95%B0%E5%92%8C%E6%9B%BF%E6%8D%A2%E5%87%BD%E6%95%B0%E5%81%9A%E4%BA%86%E4%B8%80%E4%B8%AA%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ereplace%3C%2Fspan%3E%3C%2Fspan%3E%20%E7%9A%84%E6%93%8D%E4%BD%9C%EF%BC%8C%E8%BF%99%E9%87%8C%E5%B0%B1%E6%98%AF%E6%9B%BF%E6%8D%A2%E7%9A%84%E9%80%BB%E8%BE%91%E6%89%80%E5%9C%A8%E4%BA%86%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3Efunc%20replace(target%2C%20double%20uintptr)%20%5B%5Dbyte%20%7B%5Cn%20code%20%3A%3D%20buildJmpDirective(double)%5Cn%20bytes%20%3A%3D%20entryAddress(target%2C%20len(code))%5Cn%20original%20%3A%3D%20make(%5B%5Dbyte%2C%20len(bytes))%5Cn%20copy(original%2C%20bytes)%5Cn%20modifyBinary(target%2C%20code)%5Cn%20return%20original%5Cn%7D%5Cn%5Cn%2F%2F%20%E5%85%B3%E9%94%AE%E5%87%BD%E6%95%B0%EF%BC%9A%E6%9E%84%E5%BB%BA%E8%B7%B3%E8%BD%AC%E6%8C%87%E4%BB%A4%5Cnfunc%20buildJmpDirective(double%20uintptr)%20%5B%5Dbyte%20%7B%5Cn%20%20%20%20d0%20%3A%3D%20byte(double)%5Cn%20%20%20%20d1%20%3A%3D%20byte(double%20%26gt%3B%26gt%3B%208)%5Cn%20%20%20%20d2%20%3A%3D%20byte(double%20%26gt%3B%26gt%3B%2016)%5Cn%20%20%20%20d3%20%3A%3D%20byte(double%20%26gt%3B%26gt%3B%2024)%5Cn%20%20%20%20d4%20%3A%3D%20byte(double%20%26gt%3B%26gt%3B%2032)%5Cn%20%20%20%20d5%20%3A%3D%20byte(double%20%26gt%3B%26gt%3B%2040)%5Cn%20%20%20%20d6%20%3A%3D%20byte(double%20%26gt%3B%26gt%3B%2048)%5Cn%20%20%20%20d7%20%3A%3D%20byte(double%20%26gt%3B%26gt%3B%2056)%5Cn%5Cn%20%20%20%20return%20%5B%5Dbyte%7B%5Cn%20%20%20%20%20%20%20%200x48%2C%200xBA%2C%20d0%2C%20d1%2C%20d2%2C%20d3%2C%20d4%2C%20d5%2C%20d6%2C%20d7%2C%20%2F%2F%20MOV%20rdx%2C%20double%5Cn%20%20%20%20%20%20%20%200xFF%2C%200x22%2C%20%20%20%20%20%2F%2F%20JMP%20%5Brdx%5D%5Cn%20%20%20%20%7D%5Cn%7D%5Cn%5Cn%2F%2F%20%E5%85%B3%E9%94%AE%E5%87%BD%E6%95%B0%EF%BC%9A%E9%87%8D%E5%86%99%E7%9B%AE%E6%A0%87%E5%87%BD%E6%95%B0%5Cnfunc%20modifyBinary(target%20uintptr%2C%20bytes%20%5B%5Dbyte)%20%7B%5Cn%20%20%20%20function%20%3A%3D%20entryAddress(target%2C%20len(bytes))%5Cn%5Cn%20%20%20%20page%20%3A%3D%20entryAddress(pageStart(target)%2C%20syscall.Getpagesize())%5Cn%20%20%20%20err%20%3A%3D%20syscall.Mprotect(page%2C%20syscall.PROT_READ%7Csyscall.PROT_WRITE%7Csyscall.PROT_EXEC)%5Cn%20%20%20%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20%20%20%20%20%20%20panic(err)%5Cn%20%20%20%20%7D%5Cn%20%20%20%20copy(function%2C%20bytes)%5Cn%5Cn%20%20%20%20err%20%3D%20syscall.Mprotect(page%2C%20syscall.PROT_READ%7Csyscall.PROT_EXEC)%5Cn%20%20%20%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20%20%20%20%20%20%20panic(err)%5Cn%20%20%20%20%7D%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2291%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%BB%8E%E4%B8%8A%E9%9D%A2%E7%9A%84%E4%BB%A3%E7%A0%81%E5%8F%AF%E4%BB%A5%E7%9C%8B%E5%87%BA%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EbuildJmpDirective%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%9E%84%E5%BB%BA%E4%BA%86%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%E8%B7%B3%E8%BD%AC%E7%9A%84%E6%8C%87%E4%BB%A4%EF%BC%8C%E6%8A%8A%E7%9B%AE%E6%A0%87%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88%E7%A7%BB%E5%8A%A8%E5%88%B0%E5%AF%84%E5%AD%98%E5%99%A8%20rdx%20%E4%B8%AD%EF%BC%8C%E7%84%B6%E5%90%8E%E8%B7%B3%E8%BD%AC%E5%88%B0%E5%AF%84%E5%AD%98%E5%99%A8%20rdx%20%E4%B8%AD%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88%E6%8C%87%E5%90%91%E7%9A%84%E5%9C%B0%E5%9D%80%E3%80%82%E4%B9%8B%E5%90%8E%E9%80%9A%E8%BF%87%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EmodifyBinary%3C%2Fspan%3E%3C%2Fspan%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%20%3C%2Fspan%3E%E5%87%BD%E6%95%B0%EF%BC%8C%E5%85%88%E9%80%9A%E8%BF%87%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EentryAddress%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%96%B9%E6%B3%95%E8%8E%B7%E5%8F%96%E5%88%B0%E5%8E%9F%E5%87%BD%E6%95%B0%E6%89%80%E5%9C%A8%E7%9A%84%E5%86%85%E5%AD%98%E5%9C%B0%E5%9D%80%EF%BC%8C%E4%B9%8B%E5%90%8E%E9%80%9A%E8%BF%87%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Esyscall.Mprotect%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%96%B9%E6%B3%95%E6%89%93%E5%BC%80%E5%86%85%E5%AD%98%E4%BF%9D%E6%8A%A4%EF%BC%8C%E5%B0%86%E5%87%BD%E6%95%B0%E8%B7%B3%E8%BD%AC%E6%8C%87%E4%BB%A4%E4%BB%A5%20bytes%20%E6%95%B0%E7%BB%84%E7%9A%84%E5%BD%A2%E5%BC%8F%E8%B0%83%E7%94%A8%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ecopy%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%96%B9%E6%B3%95%E5%86%99%E5%85%A5%E5%88%B0%E5%8E%9F%E5%87%BD%E6%95%B0%E6%89%80%E5%9C%A8%E5%86%85%E5%AD%98%E4%B9%8B%E4%B8%AD%EF%BC%8C%E6%9C%80%E7%BB%88%E8%BE%BE%E5%88%B0%E6%9B%BF%E6%8D%A2%E7%9A%84%E7%9B%AE%E7%9A%84%E3%80%82%E6%AD%A4%E5%A4%96%EF%BC%8C%E8%BF%99%E9%87%8C%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ereplace%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%96%B9%E6%B3%95%E8%BF%98%E4%BF%9D%E7%95%99%E4%BA%86%E5%8E%9F%E5%87%BD%E6%95%B0%E7%9A%84%E5%89%AF%E6%9C%AC%EF%BC%8C%E6%96%B9%E4%BE%BF%E5%90%8E%E7%BB%AD%E5%87%BD%E6%95%B0%20mock%20%E7%9A%84%E6%81%A2%E5%A4%8D%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2292%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%B8%BA%E4%BB%80%E4%B9%88%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EbuildJmpDirective%3C%2Fspan%3E%3C%2Fspan%3E%20%E8%A6%81%E6%9E%84%E5%BB%BA%E8%BF%99%E6%A0%B7%E7%9A%84%E8%B7%B3%E8%BD%AC%E6%8C%87%E4%BB%A4%E5%91%A2%EF%BC%9F%E8%BF%99%E9%87%8C%E5%8F%AA%E8%AF%B4%E7%BB%93%E8%AE%BA%EF%BC%8C%E5%85%B7%E4%BD%93%E7%9A%84%E6%8E%A8%E5%AF%BC%E8%BF%87%E7%A8%8B%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%EF%BC%9Ahttps%3A%2F%2Fbou.ke%2Fblog%2Fmonkey-patching-in-go%3C%2Fp%3E%3Cpre%3E%3Ccode%3Epackage%20main%5Cnfunc%20a()%20int%20%7B%20return%201%20%7D%5Cnfunc%20main()%20%7B%5Cn%20%20f%20%3A%3D%20a%5Cn%20%20f()%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2294%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%B8%8A%E9%9D%A2%E8%BF%99%E6%AE%B5%E4%BB%A3%E7%A0%81%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ea%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%98%AF%E4%B8%80%E4%B8%AA%E6%8C%87%E5%90%91%E5%87%BD%E6%95%B0%E5%AE%9E%E4%BD%93%E7%9A%84%E6%8C%87%E9%92%88%EF%BC%8C%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ef%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%98%AF%E6%8C%87%E5%90%91%E5%87%BD%E6%95%B0%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ea%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%8C%87%E9%92%88%E7%9A%84%E6%8C%87%E9%92%88%E3%80%82%E6%8A%8A%E4%B8%8A%E9%9D%A2%E5%87%BD%E6%95%B0%E7%9A%84%E8%B0%83%E7%94%A8%E5%8F%8D%E6%B1%87%E7%BC%96%EF%BC%8C%E8%83%BD%E5%A4%9F%E7%9C%8B%E5%88%B0%E6%93%8D%E4%BD%9C%E5%AF%84%E5%AD%98%E5%99%A8%E7%9A%84%E5%85%B7%E4%BD%93%E7%BB%86%E8%8A%82%E3%80%82%EF%BC%88%20%E5%A6%82%E6%9E%9C%E5%AF%B9%E6%B1%87%E7%BC%96%E4%B8%8D%E6%98%AF%E5%BE%88%E4%BA%86%E8%A7%A3%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%85%88%E9%98%85%E8%AF%BB%20http%3A%2F%2Fwww.ruanyifeng.com%2Fblog%2F2018%2F01%2Fassembly-language-primer.html%20%EF%BC%89%3C%2Fp%3E%3Cdiv%20class%3D%5C%22pgc-img%5C%22%3E%3Cimg%20src%3D%5C%22https%3A%2F%2Fp3-sign.toutiaoimg.com%2Ftos-cn-i-qvj2lq49k0%2F2f1220bbf1064c8a9eb83d7188697332~tplv-tt-origin-web%3Agif.jpeg%3F_iz%3D58558%26from%3Darticle.pc_detail%26lk3s%3D953192f4%26x-expires%3D1734609857%26x-signature%3D6LvsZwDUwu%252BW76ZO0A0u9onC%252BDQ%253D%5C%22%20img_width%3D%5C%22884%5C%22%20img_height%3D%5C%2286%5C%22%20image_type%3D%5C%221%5C%22%20mime_type%3D%5C%22image%2Fjpeg%5C%22%20web_uri%3D%5C%22tos-cn-i-qvj2lq49k0%2F2f1220bbf1064c8a9eb83d7188697332%5C%22%3E%3Cp%20class%3D%5C%22pgc-img-caption%5C%22%3E%3C%2Fp%3E%3C%2Fdiv%3E%3Cp%20data-track%3D%5C%2295%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%AC%AC%E4%B8%80%E8%A1%8C%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Elea%3C%2Fspan%3E%3C%2Fspan%3E%20%E4%B8%BA%20load%20effective%20address%EF%BC%8C%E8%BF%99%E9%87%8C%E6%98%AF%E5%B0%86%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%231E6BB8%3B%5C%22%3Ef%3C%2Fspan%3E%20%E5%8F%98%E9%87%8F%E8%BF%99%E4%B8%AA%E5%80%BC%E7%9B%B4%E6%8E%A5%E8%B5%8B%E7%BB%99%20rdx%20%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%8C%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ef%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%8F%98%E9%87%8F%E7%9A%84%E5%80%BC%E6%98%AF%E6%8C%87%E5%90%91%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ea%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E7%9A%84%E5%9C%B0%E5%9D%80%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2296%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%AC%AC%E4%BA%8C%E8%A1%8C%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Emov%3C%2Fspan%3E%3C%2Fspan%3E%20%E8%A1%A8%E7%A4%BA%E7%A7%BB%E5%8A%A8%EF%BC%8C%E8%BF%99%E9%87%8C%E6%98%AF%E5%8F%96%E5%88%B0%E5%86%85%E5%AD%98%E5%9C%B0%E5%9D%80%E4%B8%BA%20rdx%20%E7%9A%84%E6%95%B0%E6%8D%AE%E8%B5%8B%E5%80%BC%E7%BB%99%20rbx%EF%BC%8C%E6%AD%A4%E6%97%B6%E5%86%85%E5%AD%98%E5%9C%B0%E5%9D%80%20rbx%20%E6%8C%87%E5%90%91%E7%9A%84%E5%88%9A%E5%A5%BD%E5%B0%B1%E6%98%AF%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ea%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2297%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%9C%80%E5%90%8E%EF%BC%8C%E8%B0%83%E7%94%A8%20rbx%20%E9%87%8C%E9%9D%A2%E7%9A%84%E5%86%85%E5%AE%B9%EF%BC%8C%E5%85%B6%E5%AE%9E%E4%B9%9F%E5%B0%B1%E6%98%AF%E6%89%A7%E8%A1%8C%E5%87%BD%E6%95%B0%E4%BD%93%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2298%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9B%A0%E6%AD%A4%EF%BC%8C%E6%88%91%E4%BB%AC%E6%83%B3%E6%94%B9%E5%86%99%E5%87%BD%E6%95%B0%EF%BC%8C%E5%8F%AA%E8%A6%81%E6%83%B3%E5%8A%9E%E6%B3%95%E6%8A%8A%E9%9C%80%E8%A6%81%E8%B7%B3%E8%BD%AC%E7%9A%84%E5%87%BD%E6%95%B0%E7%9A%84%E5%9C%B0%E5%9D%80%E5%8A%A0%E8%BD%BD%E5%88%B0%20rdx%20%E5%AF%84%E5%AD%98%E5%99%A8%E4%B8%AD%EF%BC%8C%E4%B9%8B%E5%90%8E%E4%BD%BF%E7%94%A8%E6%8C%87%E4%BB%A4%E8%B7%B3%E8%BD%AC%E6%89%A7%E8%A1%8C%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cpre%3E%3Ccode%3EMOV%20rdx%2C%20double%5CnJMP%20%5Brdx%5D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%22100%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%9C%80%E7%BB%88%EF%BC%8C%E6%8A%8A%E6%B1%87%E7%BC%96%E6%8C%87%E4%BB%A4%E7%BF%BB%E8%AF%91%E6%88%90%20go%20%E8%83%BD%E5%A4%9F%E8%AF%86%E5%88%AB%E7%9A%84%E7%89%88%E6%9C%AC%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%22101%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%BF%99%E5%85%B6%E5%AE%9E%E4%B9%9F%E6%98%AF%E6%B1%87%E7%BC%96%E9%87%8C%E9%9D%A2%E5%BE%88%E5%B8%B8%E8%A7%81%E7%9A%84%E7%83%AD%E8%A1%A5%E4%B8%81%EF%BC%8C%E5%A4%9A%E7%94%A8%E4%BA%8E%E8%BF%9B%E7%A8%8B%E4%B8%AD%E5%87%BD%E6%95%B0%E7%9A%84%E6%9B%BF%E6%8D%A2%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%22102%5C%22%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233D89FF%3B%20--tt-darkmode-color%3A%20%233D89FF%3B%5C%22%3EQ2%EF%BC%9A%E6%89%A7%E8%A1%8C%20-gcflags%3Dall%3D-l%20%E5%85%B7%E4%BD%93%E6%9C%89%E4%BB%80%E4%B9%88%E4%BD%9C%E7%94%A8%3C%2Fspan%3E%3C%2Fstrong%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%22103%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E-gcflags%3C%2Fspan%3E%3C%2Fspan%3E%20%E7%94%A8%E4%BA%8E%E5%9C%A8%20go%20%E7%BC%96%E8%AF%91%E6%9E%84%E5%BB%BA%E6%97%B6%E8%BF%9B%E8%A1%8C%E5%8F%82%E6%95%B0%E7%9A%84%E4%BC%A0%E9%80%92%EF%BC%8C%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Eall%3C%2Fspan%3E%3C%2Fspan%3E%20%E8%A1%A8%E7%A4%BA%E8%A6%86%E7%9B%96%E6%89%80%E6%9C%89%E5%9C%A8%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EGOPATH%3C%2Fspan%3E%3C%2Fspan%3E%20%E4%B8%AD%E7%9A%84%E5%8C%85%EF%BC%8C%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E-l%3C%2Fspan%3E%3C%2Fspan%3E%20%E8%A1%A8%E7%A4%BA%E7%A6%81%E6%AD%A2%E7%BC%96%E8%AF%91%E7%9A%84%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E3%80%82%E8%AF%A5%E6%8C%87%E4%BB%A4%E5%8F%AF%E4%BB%A5%E9%98%B2%E6%AD%A2%E7%BC%96%E8%AF%91%E6%97%B6%E4%BB%A3%E7%A0%81%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E4%BD%BF%E5%BE%97%20mock%20%E5%A4%B1%E8%B4%A5%EF%BC%8C%3Cstrong%3E%E6%9C%80%E7%BB%88%E5%AF%BC%E8%87%B4%E6%89%A7%E8%A1%8C%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%8D%E9%80%9A%E8%BF%87%3C%2Fstrong%3E%E3%80%82%E4%B8%8B%E9%9D%A2%E6%88%91%E4%BB%AC%E5%85%B7%E4%BD%93%E6%9D%A5%E6%8E%A2%E8%AE%A8%E4%B8%80%E4%B8%8B%E2%80%9C%E5%86%85%E8%81%94%E2%80%9D%E4%BB%A5%E5%8F%8A%E7%BB%99%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E5%B8%A6%E6%9D%A5%E7%9A%84%E5%BD%B1%E5%93%8D%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%22104%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E9%80%9A%E4%BF%97%E6%9D%A5%E8%AE%B2%EF%BC%8C%E5%86%85%E8%81%94%E6%8C%87%E7%9A%84%E6%98%AF%E6%8A%8A%E7%AE%80%E7%9F%AD%E7%9A%84%E5%87%BD%E6%95%B0%E5%9C%A8%E8%B0%83%E7%94%A8%E5%AE%83%E7%9A%84%E5%9C%B0%E6%96%B9%E5%B1%95%E5%BC%80%E3%80%82%E7%94%B1%E4%BA%8E%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E6%9C%89%E5%9B%BA%E5%AE%9A%E7%9A%84%E5%BC%80%E9%94%80%EF%BC%88%E6%A0%88%E5%92%8C%E6%8A%A2%E5%8D%A0%E6%A3%80%E6%9F%A5%EF%BC%89%EF%BC%8C%E5%9C%A8%E7%BC%96%E8%AF%91%E8%BF%87%E7%A8%8B%E4%B8%AD%EF%BC%8C%E7%BC%96%E8%AF%91%E5%99%A8%E5%8F%AF%E4%BB%A5%E9%92%88%E5%AF%B9%E4%BB%A3%E7%A0%81%E8%BF%9B%E8%A1%8C%E5%86%85%E8%81%94%EF%BC%8C%E5%87%8F%E5%B0%91%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E5%BC%80%E9%94%80%E3%80%82%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E6%98%AF%E9%AB%98%E6%80%A7%E8%83%BD%E7%BC%96%E7%A8%8B%E7%9A%84%E4%B8%80%E7%A7%8D%E9%87%8D%E8%A6%81%E6%89%8B%E6%AE%B5%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%22105%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9C%A8%20go%20%E4%B8%AD%EF%BC%8C%E7%BC%96%E8%AF%91%E5%99%A8%E4%B8%8D%E4%BC%9A%E5%AF%B9%E6%89%80%E6%9C%89%E7%AE%80%E5%8D%95%E5%87%BD%E6%95%B0%E8%BF%9B%E8%A1%8C%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E3%80%82go%20%E5%9C%A8%E5%86%B3%E7%AD%96%E6%98%AF%E5%90%A6%E8%A6%81%E5%AF%B9%E5%87%BD%E6%95%B0%E8%BF%9B%E8%A1%8C%E5%86%85%E8%81%94%E6%97%B6%E6%9C%89%E4%B8%80%E4%B8%AA%E6%A0%87%E5%87%86%EF%BC%9A%E5%87%BD%3C%2Fspan%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%95%B0%E4%BD%93%E5%86%85%E5%8C%85%E5%90%AB%EF%BC%9A%E9%97%AD%E5%8C%85%E8%B0%83%E7%94%A8%EF%BC%8Cselect%20%EF%BC%8Cfor%20%EF%BC%8Cdefer%EF%BC%8Cgo%20%E5%85%B3%E9%94%AE%E5%AD%97%E7%9A%84%E7%9A%84%E5%87%BD%E6%95%B0%E4%B8%8D%E4%BC%9A%E8%BF%9B%E8%A1%8C%E5%86%85%E8%81%94%E3%80%82%E5%B9%B6%E4%B8%94%E9%99%A4%E4%BA%86%E8%BF%99%E4%BA%9B%EF%BC%8C%E8%BF%98%E6%9C%89%E5%85%B6%E5%AE%83%E7%9A%84%E9%99%90%E5%88%B6%E3%80%82%E5%BD%93%E8%A7%A3%E6%9E%90%20AST%20%E6%97%B6%EF%BC%8CGo%20%E7%94%B3%E8%AF%B7%E4%BA%86%2080%20%E4%B8%AA%E8%8A%82%E7%82%B9%E4%BD%9C%E4%B8%BA%E5%86%85%E8%81%94%E7%9A%84%E9%A2%84%E7%AE%97%E3%80%82%E6%AF%8F%E4%B8%AA%E8%8A%82%E7%82%B9%E9%83%BD%E4%BC%9A%E6%B6%88%E8%80%97%E4%B8%80%E4%B8%AA%E9%A2%84%E7%AE%97%E3%80%82%E5%BD%93%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%E7%9A%84%E5%BC%80%E9%94%80%E8%B6%85%E8%BF%87%E4%BA%86%E8%BF%99%E4%B8%AA%E9%A2%84%E7%AE%97%EF%BC%8C%E5%B0%B1%E6%97%A0%E6%B3%95%E5%86%85%E8%81%94%E3%80%82%3C%2Fspan%3E%3C%2Fstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%EF%BC%88%20%E5%8F%82%E8%80%83%E8%87%AA%EF%BC%9Ahttps%3A%2F%2Fjuejin.cn%2Fpost%2F6924888439577903117%20%EF%BC%89%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%22106%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%B8%8B%E9%9D%A2%E6%88%91%E4%BB%AC%E9%80%9A%E8%BF%87%E4%B8%80%E6%AE%B5%E7%AE%80%E7%9F%AD%E7%9A%84%E4%BB%A3%E7%A0%81%E6%9D%A5%E7%90%86%E8%A7%A3%20go%20%E7%BC%96%E8%AF%91%E8%BF%87%E7%A8%8B%E7%9A%84%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E8%BF%87%E7%A8%8B%E3%80%82%E6%88%91%E4%BB%AC%E4%BB%8E%20gomonkey%20%E5%85%B3%E4%BA%8E%E5%86%85%E8%81%94%E7%9A%84%20issue%20%E6%91%98%E5%8F%96%E4%BA%86%E4%B8%80%E6%AE%B5%E4%BB%A3%E7%A0%81%EF%BC%9A%3C%2Fspan%3E%3C%2Fp%3E%3Cpre%3E%3Ccode%3Epackage%20main%5Cnimport%20%26%2334%3Bfmt%26%2334%3B%5Cnfunc%20G2()%20string%20%7B%20%20return%20%26%2334%3BG2%26%2334%3B%20%7D%5Cnfunc%20G()%20string%20%7B%20%20return%20G2()%20%7D%5Cnfunc%20main()%20%7B%5Cn%20%20g%20%3A%3D%20G()%5Cn%20%20fmt.Println(g)%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%22108%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%B8%8A%E9%9D%A2%E8%BF%99%E6%AE%B5%E4%BB%A3%E7%A0%81%E5%BE%88%E7%AE%80%E5%8D%95%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Emain%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E4%B8%AD%E8%B0%83%E7%94%A8%E4%BA%86%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E6%8B%BF%E5%88%B0%E8%BF%94%E5%9B%9E%E5%80%BC%E8%B5%8B%E5%80%BC%E5%8F%98%E9%87%8F%E7%BB%99%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Eg%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%90%8E%E6%89%93%E5%8D%B0%E7%BB%93%E6%9E%9C%E3%80%82%E5%85%B6%E4%B8%AD%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E4%BA%86%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG2%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%EF%BC%8C%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG2%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E8%BF%94%E5%9B%9E%E4%BA%86%E5%AD%97%E7%AC%A6%E4%B8%B2%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%26%2334%3BG2%26%2334%3B%3C%2Fspan%3E%3C%2Fspan%3E%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%22109%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%84%B6%E8%80%8C%EF%BC%8C%E7%BB%8F%E8%BF%87%E7%BC%96%E8%AF%91%E5%99%A8%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E5%90%8E%E7%9A%84%E4%BB%A3%E7%A0%81%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E5%AE%9E%E9%99%85%E8%A2%AB%E5%B1%95%E5%BC%80%E4%BA%86%EF%BC%8C%E6%9C%80%E7%BB%88%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Emain%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E8%A2%AB%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E6%88%90%EF%BC%9A%3C%2Fp%3E%3Cpre%3E%3Ccode%3Efunc%20main()%20%7B%5Cn%20%20%2F%2F%20%E5%B1%95%E5%BC%80%20g%20%3A%3D%20G()%5Cn%20%20%2F%2F%20%3D%26gt%3B%20g%20%3A%3D%20%26%2334%3BG2%26%2334%3B%5Cn%5Cn%20%20%2F%2F%20%E5%B1%95%E5%BC%80%20fmt.Println(g)%5Cn%20%20%2F%2F%20%3D%26gt%3B%20%E7%9B%B8%E5%85%B3%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%22111%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%8F%AF%E8%A7%81%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E5%92%8C%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG2%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E5%8E%9F%E6%9C%AC%E6%89%A7%E8%A1%8C%E6%97%B6%E5%80%99%E5%B8%A6%E6%9D%A5%E5%87%BD%E6%95%B0%E6%A0%88%E7%94%B3%E8%AF%B7%E5%9B%9E%E6%94%B6%EF%BC%8C%E4%BC%98%E5%8C%96%E8%BF%87%E5%90%8E%E5%B0%86%E4%B8%8D%E5%86%8D%E6%9C%89%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%22112%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%BF%99%E9%87%8C%E6%88%91%E4%BB%AC%E6%89%A7%E8%A1%8C%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ego%20run%20-gcflags%3D%26%2334%3B-m%20-m%26%2334%3B%20main.go%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%9D%A5%E6%9F%A5%E7%9C%8B%E7%BC%96%E8%AF%91%E5%9C%A8%E8%BF%9B%E8%A1%8C%E4%BB%A5%E4%B8%8A%E4%BB%A3%E7%A0%81%E7%9A%84%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3E%E2%98%81%EF%B8%8F%20%20test%20%20go%20run%20-gcflags%3D%26%2334%3B-m%20-m%26%2334%3B%20main.go%5Cn%23%20command-line-arguments%5Cn.%2Fmain.go%3A5%3A6%3A%20can%20inline%20G2%20as%3A%20func()%20string%20%7B%20return%20%26%2334%3BG2%26%2334%3B%20%7D%20.%2Fmain.go%3A9%3A6%3A%20can%20inline%20G%20as%3A%20func()%20string%20%7B%20return%20G2()%20%7D%20.%2Fmain.go%3A10%3A11%3A%20inlining%20call%20to%20G2%20func()%20string%20%7B%20return%20%26%2334%3BG2%26%2334%3B%20%7D%20.%2Fmain.go%3A13%3A6%3A%20cannot%20inline%20main%3A%20function%20too%20complex%3A%20cost%2087%20exceeds%20budget%2080%5Cn.%2Fmain.go%3A14%3A8%3A%20inlining%20call%20to%20G%20func()%20string%20%7B%20return%20G2()%20%7D%20.%2Fmain.go%3A14%3A8%3A%20inlining%20call%20to%20G2%20func()%20string%20%7B%20return%20%26%2334%3BG2%26%2334%3B%20%7D%20.%2Fmain.go%3A15%3A13%3A%20inlining%20call%20to%20fmt.Println%20func(...interface%20%7B%7D)%20(int%2C%20error)%20%7B%20var%20fmt..autotmp_3%20int%3B%20fmt..autotmp_3%20%3D%20%26lt%3BN%26gt%3B%3B%20var%20fmt..autotmp_4%20error%3B%20fmt..autotmp_4%20%3D%20%26lt%3BN%26gt%3B%3B%20fmt..autotmp_3%2C%20fmt..autotmp_4%20%3D%20fmt.Fprintln(io.Writer(os.Stdout)%2C%20fmt.a...)%3B%20return%20fmt..autotmp_3%2C%20fmt..autotmp_4%20%7D%5Cn.%2Fmain.go%3A15%3A13%3A%20g%20escapes%20to%20heap%20.%2Fmain.go%3A15%3A13%3A%20main%20%5B%5Dinterface%20%7B%7D%20literal%20does%20not%20escape%5Cn.%2Fmain.go%3A15%3A13%3A%20io.Writer(os.Stdout)%20escapes%20to%20heap%20%26lt%3Bautogenerated%26gt%3B%3A1%3A%20(*File).close%20.this%20does%20not%20escape%20G2%5Cn%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%22114%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%BB%8E%E6%89%93%E5%8D%B0%E5%87%BA%E7%9A%84%E5%86%85%E5%AE%B9%E5%8F%AF%E4%BB%A5%E7%9C%8B%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG2%5C%5CG%5C%5Cfmt.Println%3C%2Fspan%3E%3C%2Fspan%3E%20%E9%83%BD%E8%A2%AB%E5%86%85%E8%81%94%E4%BA%86%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%22115%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%B8%8A%E9%9D%A2%E6%8F%90%E5%88%B0%E4%BA%86%20gomokey%20%E6%89%93%E6%A1%A9%E7%9A%84%E9%80%BB%E8%BE%91%EF%BC%8C%E5%AE%83%E6%98%AF%E5%9C%A8%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E7%9A%84%E6%97%B6%E5%80%99%E9%80%9A%E8%BF%87%E6%9C%BA%E5%99%A8%E6%8C%87%E4%BB%A4%E5%B0%86%E5%87%BD%E6%95%B0%E7%9A%84%E6%8C%87%E5%90%91%E6%9B%BF%E6%8D%A2%E4%BA%86%E3%80%82%E7%94%B1%E4%BA%8E%E5%87%BD%E6%95%B0%E7%BC%96%E8%AF%91%E5%90%8E%E8%A2%AB%E5%86%85%E8%81%94%EF%BC%8C%E5%AE%9E%E9%99%85%E4%B8%8A%E4%B8%8D%E5%AD%98%E5%9C%A8%E5%87%BD%E6%95%B0%E7%9A%84%E8%B0%83%E7%94%A8%EF%BC%8C%E5%AF%BC%E8%87%B4%E5%8D%95%E6%B5%8B%E6%89%A7%E8%A1%8C%E4%B8%8D%E9%80%9A%E8%BF%87%EF%BC%8C%E8%BF%99%E4%B9%9F%E6%98%AF%E5%86%85%E8%81%94%E5%AF%BC%E8%87%B4%20gomonkey%20%E6%89%93%E6%A1%A9%E6%97%A0%E6%95%88%E7%9A%84%E9%97%AE%E9%A2%98%E6%89%80%E5%9C%A8%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20style%3D%5C%22text-align%3A%20center%3B%5C%22%20data-track%3D%5C%22120%5C%22%3E%3Cspan%20style%3D%5C%22letter-spacing%3A%201px%3B%5C%22%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%23FFFFFF%3B%20--tt-darkmode-color%3A%20%23FFFFFF%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23138BDE%3B%20--tt-darkmode-bgcolor%3A%20%23138BDE%3B%5C%22%3E%E5%86%99%E5%9C%A8%E6%9C%80%E5%90%8E%3C%2Fspan%3E%3C%2Fspan%3E%3C%2Fstrong%3E%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%22121%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%23111111%3B%20--tt-darkmode-color%3A%20%23A3A3A3%3B%5C%22%3EFreemen%20App%E6%98%AF%E4%B8%80%E6%AC%BE%E4%B8%93%E6%B3%A8%E4%BA%8EIT%E7%A8%8B%E5%BA%8F%E5%91%98%E6%B1%82%E8%81%8C%E6%8B%9B%E8%81%98%E7%9A%84%E4%B8%80%E4%B8%AA%E6%B1%82%E8%81%8C%E5%B9%B3%E5%8F%B0%EF%BC%8C%E6%97%A8%E5%9C%A8%E5%B8%AE%E5%8A%A9IT%E6%8A%80%E6%9C%AF%E5%B7%A5%E4%BD%9C%E8%80%85%E8%83%BD%E6%9B%B4%E5%A5%BD%E6%9B%B4%E5%BF%AB%E5%85%A5%E8%81%8C%E5%8F%8A%E5%8A%AA%E5%8A%9B%E5%8D%8F%E8%B0%83IT%E6%8A%80%E6%9C%AF%E8%80%85%E5%B7%A5%E4%BD%9C%E5%92%8C%E7%94%9F%E6%B4%BB%E7%9A%84%E5%85%B3%E7%B3%BB%EF%BC%8C%E8%AE%A9%E5%B7%A5%E4%BD%9C%E6%9B%B4%E8%87%AA%E7%94%B1%EF%BC%81%3C%2Fspan%3E%3C%2Fp%3E%3Cdiv%20class%3D%5C%22pgc-img%5C%22%3E%3Cimg%20src%3D%5C%22https%3A%2F%2Fp3-sign.toutiaoimg.com%2Ftos-cn-i-qvj2lq49k0%2F4f76255f3b074051aac9d049e5fe72ea~tplv-tt-origin-web%3Agif.jpeg%3F_iz%3D58558%26from%3Darticle.pc_detail%26lk3s%3D953192f4%26x-expires%3D1734609857%26x-signature%3DHmsxOGVN213kq4mh2c3SQZOiCLQ%253D%5C%22%20img_width%3D%5C%221024%5C%22%20img_height%3D%5C%22512%5C%22%20image_type%3D%5C%221%5C%22%20mime_type%3D%5C%22image%2Fpng%5C%22%20web_uri%3D%5C%22tos-cn-i-qvj2lq49k0%2F4f76255f3b074051aac9d049e5fe72ea%5C%22%3E%3Cp%20class%3D%5C%22pgc-img-caption%5C%22%3E%3C%2Fp%3E%3C%2Fdiv%3E%3Cp%20data-track%3D%5C%22123%5C%22%3E%E6%9C%AC%E6%96%87%E8%BD%AC%E8%BD%BD%E8%87%AA%3Cspan%20style%3D%5C%22letter-spacing%3A%201px%3B%5C%22%3E%E8%85%BE%E8%AE%AF%E6%8A%80%E6%9C%AF%E5%B7%A5%E7%A8%8B%3C%2Fspan%3E%3C%2Fp%3E%22%2C%22imageList%22%3A%5B%22https%3A%2F%2Fp3-sign.toutiaoimg.com%2Ftos-cn-i-qvj2lq49k0%2Fe108da3ebb3741d7af7665d5a59ff21c~tplv-tt-origin-web%3Agif.jpeg%3F_iz%3D58558%26from%3Darticle.pc_detail%26lk3s%3D953192f4%26x-expires%3D1734609857%26x-signature%3DVvb2b50Q84K4UtpZubecV0HS6HQ%253D%22%2C%22https%3A%2F%2Fp3-sign.toutiaoimg.com%2Ftos-cn-i-qvj2lq49k0%2F2f1220bbf1064c8a9eb83d7188697332~tplv-tt-origin-web%3Agif.jpeg%3F_iz%3D58558%26from%3Darticle.pc_detail%26lk3s%3D953192f4%26x-expires%3D1734609857%26x-signature%3D6LvsZwDUwu%252BW76ZO0A0u9onC%252BDQ%253D%22%2C%22https%3A%2F%2Fp3-sign.toutiaoimg.com%2Ftos-cn-i-qvj2lq49k0%2F4f76255f3b074051aac9d049e5fe72ea~tplv-tt-origin-web%3Agif.jpeg%3F_iz%3D58558%26from%3Darticle.pc_detail%26lk3s%3D953192f4%26x-expires%3D1734609857%26x-signature%3DHmsxOGVN213kq4mh2c3SQZOiCLQ%253D%22%5D%2C%22mediaInfo%22%3A%7B%22userId%22%3A%22MS4wLjABAAAAJOciZkc9eBL9yaD0sqJ6EvcVuBksXQMzilpmr2mk6bGNzfFMOA1wkQR9ctLoqvqA%22%2C%22unsafeUserId%22%3A%223404510121171997%22%2C%22name%22%3A%22Freemen%E7%A8%8B%E5%BA%8F%E5%91%98%E6%8B%9B%E8%81%98app%22%2C%22avatarUrl%22%3A%22https%3A%2F%2Fsf3-cdn-tos.toutiaostatic.com%2Fimg%2Fuser-avatar%2F7c3277bf677f5aaccc5e9d913fab74bf~300x300.image%22%2C%22description%22%3A%22%22%2C%22userVerified%22%3A1%7D%2C%22seoTDK%22%3A%7B%22title%22%3A%22%E2%80%8B%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%20Golang%20%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%20-%20%E4%BB%8A%E6%97%A5%E5%A4%B4%E6%9D%A1%22%2C%22description%22%3A%22%E5%BC%95%E5%85%A5%E9%9A%8F%E7%9D%80%E5%B7%A5%E7%A8%8B%E5%8C%96%E5%BC%80%E5%8F%91%E7%9A%84%E5%86%85%E5%A4%A7%E5%8A%9B%E7%9A%84%E6%8E%A8%E5%B9%BF%EF%BC%8C%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%B6%8A%E6%9D%A5%E8%B6%8A%E5%8F%97%E5%88%B0%E5%B9%BF%E5%A4%A7%E5%BC%80%E5%8F%91%E8%80%85%E7%9A%84%E9%87%8D%E8%A7%86%E3%80%82%E5%9C%A8%E5%AD%A6%E4%B9%A0%E7%9A%84%E8%BF%87%E7%A8%8B%E4%B8%AD%EF%BC%8C%E5%8F%91%E7%8E%B0%E7%BD%91%E4%B8%8A%E9%92%88%E5%AF%B9%20Golang%20%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E5%A4%A7%E5%A4%9A%E4%BB%8E%E7%90%86%E8%AE%BA%E8%A7%92%E5%BA%A6%E5%87%BA%E5%8F%91%E4%BB%8B%E7%BB%8D%EF%BC%8C%E7%BC%BA%E4%B9%8F%E5%AE%8C%E6%95%B4%E7%9A%84%E5%AE%9E%E4%BE%8B%E8%AF%B4%E6%98%8E%EF%BC%8C%E6%99%A6%E6%B6%A9%E9%9A%BE%E6%87%82%E7%9A%84%20API%20%E8%AE%A9%E5%88%9D%E5%AD%A6%E6%8E%A5%E8%A7%A6%E8%80%85%E9%9A%BE%E4%BB%A5%E4%B8%8B%E6%89%8B%E3%80%82%22%2C%22keywords%22%3A%22Redis%2CJSON%2C%E6%95%B0%E6%8D%AE%E5%BA%93%22%2C%22publishTimestamp%22%3A%221675131752%22%2C%22modifiedTimestamp%22%3A%221732295492%22%7D%2C%22cover%22%3A%22https%3A%2F%2Fp3-sign.toutiaoimg.com%2Ftos-cn-i-qvj2lq49k0%2Fdaacfeb901cb47cb8e5075aeedbff19e~tplv-tt-shrink-asy2-web%3A640%3A0%3A5aS05p2hQEZyZWVtZW7nqIvluo_lkZjmi5vogZhhcHA%3D%3Agif.jpeg%3F_iz%3D58558%26from%3Darticle.pc_detail%26lk3s%3D953192f4%26x-expires%3D1734609857%26x-signature%3DscoITv0VcHY%252BEtz9UlBpf9nBIRo%253D%22%2C%22logId%22%3A%2220241212200417150715FEE0C436C97040%22%2C%22sylpageConfig%22%3A%7B%22card%22%3A%7B%22id%22%3A%22%22%7D%7D%2C%22identity%22%3A%7B%22web_id%22%3A%227447494372893656587%22%2C%22user_is_login%22%3Afalse%7D%2C%22abtestInfo%22%3A%7B%22rsp_type%22%3A5%2C%22version_name%22%3A%224938400%2C8813385%22%2C%22parameters%22%3A%7B%22filter%22%3A%7B%22debug_enable_pc_small_video%22%3Afalse%2C%22enable_pc_small_video%22%3Atrue%7D%2C%22home_nav_conf%22%3A%7B%22dcd_out%22%3A1%7D%2C%22optimus%22%3A%7B%22rule_rank_rules%22%3A%22ranking_rule_list%20%7B%5Cn%20%20id%3A%201221233%5Cn%20priority%3A%200%5Cn%20tags%3A%20%5C%2212123%5C%22%5Cn%20%20enabled%3A%20true%5Cn%20%20type%3A%20CARD%5Cn%20%20card_rule%20%7B%5Cn%20size%3A%202%5Cn%20type%3A%20SAME_SLOT%20%5Cn%7D%5Cn%20%7D%5Cn%20ranking_rule_list%20%7B%5Cn%20%20id%3A%2020458%5Cn%20%20priority%3A%203%5Cn%20%20enabled%3A%20true%5Cn%20%20category%3A%2020458%5Cn%20%20type%3A%20WINDOW%5Cn%20%20window_rule%20%7B%5Cn%20%20%20%20type%3A%20SLIDE%5Cn%20%20%20%20size%3A%203%5Cn%20%20%20%20max%3A%201%5Cn%20%20%7D%5Cn%7D%5Cn%20ranking_rule_list%20%7B%5Cn%20%20id%3A%201111024%5Cn%20priority%3A%200%5Cn%20tags%3A%20%5C%2211024%5C%22%5Cn%20%20enabled%3A%20true%5Cn%20%20type%3A%20CARD%5Cn%20%20card_rule%20%7B%5Cn%20size%3A%206%5Cn%20type%3A%20SAME_SLOT%20%5Cn%7D%5Cn%20%7D%22%7D%2C%22page_upgrade%22%3A%7B%22new_profile%22%3Atrue%2C%22video_double_column%22%3Atrue%7D%2C%22recall%22%3A%7B%22debug_filter_reason_list%22%3A%5B%5D%2C%22debug_recall_reason_list%22%3A%5B70%2C71%2C72%2C73%2C80%2C83%5D%2C%22enable_debug_filter_reason%22%3Atrue%2C%22enable_debug_recall_reason%22%3Atrue%2C%22friend_feed%22%3A%7B%22control_nums%22%3A1500%2C%22count%22%3A1000%2C%22enable%22%3Atrue%2C%22enable_cpp_friend_feed%22%3Atrue%2C%22enable_friend_feed_container_filter%22%3Atrue%2C%22enable_group_status_filter%22%3Atrue%2C%22params%22%3A%7B%7D%2C%22top_k%22%3A10%2C%22use_new_friend_recall%22%3Atrue%2C%22valid_group_source%22%3A%5B2%2C5%2C15%2C23%2C16%2C19%2C21%2C132%5D%2C%22weight%22%3A20%7D%7D%2C%22seraph%22%3A%7B%22rule_rank_rules_pc_small%22%3A%22%5Cn%20%20%20%20%20%20ranking_rule_list%20%7B%5Cn%20%20%20%20%20%20%20%20%20id%3A%2022124%20%5Cn%20%20%20%20%20%20%20%20%20priority%3A%200%20%5Cn%20%20%20%20%20%20%20%20%20tags%3A%20%5C%2222124%5C%22%20%5Cn%20%20%20%20%20%20%20%20%20enabled%3A%20true%20%5Cn%20%20%20%20%20%20%20%20%20type%3A%20CARD%20%5Cn%20%20%20%20%20%20%20%20%20card_rule%20%7B%20%5Cn%20%20%20%20%20%20%20%20%20size%3A%206%20%5Cn%20%20%20%20%20%20%20%20%20num_cards%3A%201%5Cn%20%20%20%20%20%20%20%20%20type%3A%20SAME_SLOT%20%5Cn%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%22%2C%22rule_rank_rules_pc_small_window%22%3A%22%5Cn%20%20%20%20%20%20ranking_rule_list%20%7B%5Cn%20%20%20%20id%3A%20222124%5Cn%20%20%20priority%3A%200%5Cn%20%20%20tags%3A%20%5C%2222124%5C%22%5Cn%20%20%20%20enabled%3A%20false%5Cn%20%20%20%20type%3A%20WINDOW%5Cn%20%20%20%20window_rule%20%7B%5Cn%20%20%20type%3A%20SLIDE%20%5Cn%20%20%20size%3A%2012%20%5Cn%20%20%20max%3A%206%20%5Cn%20%20%20%7D%5Cn%20%20%20%7D%22%7D%2C%22small_sort%22%3A%7B%22enable_filter_zhanwai%22%3Atrue%2C%22filter_genre_plog%22%3Afalse%2C%22filter_genre_small%22%3Afalse%2C%22skip_small_app_version_filter%22%3Afalse%2C%22skip_small_genre_filter%22%3Afalse%7D%2C%22sort%22%3A%7B%22allowed_ticai%22%3A%5B%22forum_post%22%2C%22pgc_text%22%2C%22pgc_video%22%2C%22short_video%22%5D%2C%22enable_optimus_gen_pc_mv_card%22%3Atrue%2C%22enable_optimus_gen_pc_sv_card%22%3Atrue%2C%22enable_pc_skip_app_smallvideo_card%22%3Atrue%7D%2C%22stream%22%3A%7B%22disable_related%22%3Atrue%2C%22enable_ads_sdk%22%3Atrue%2C%22enable_ads_sdk_pack%22%3Atrue%7D%2C%22ugc_sort%22%3A%7B%22expore_smallvideo%22%3Atrue%7D%2C%22video_channel%22%3A%7B%22rank%22%3A5%2C%22use_feed%22%3A1%7D%7D%2C%22env_flag%22%3A0%2C%22ns_parameters%22%3A%7B%7D%2C%22object_parameters%22%3A%7B%7D%7D%2C%22localCityInfo%22%3A%7B%22name%22%3A%22%E8%B4%BA%E5%B7%9E%22%2C%22code%22%3A%22451100%22%2C%22channelId%22%3A3202164680%7D%2C%22voteLink%22%3A%5B%7B%22keyword%22%3A%22Us%20Aaj%20Tak%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767723009%22%7D%2C%7B%22keyword%22%3A%22Thori%20Pee%20Layi%20Te%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767673857%22%7D%2C%7B%22keyword%22%3A%22Tetho%20Dil%20Mangya%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767624705%22%7D%2C%7B%22keyword%22%3A%22Sada%20Sarghoday%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767559169%22%7D%2C%7B%22keyword%22%3A%22Laiyan%20Laiyan%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767477249%22%7D%2C%7B%22keyword%22%3A%22Dil%20Sada%20Naal%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767411713%22%7D%2C%7B%22keyword%22%3A%22Beli%20Barna%20Ke%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767346177%22%7D%2C%7B%22keyword%22%3A%22Sajna%20Siwa%20Asan%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767231489%22%7D%2C%7B%22keyword%22%3A%22New%20Qasida%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767149569%22%7D%2C%7B%22keyword%22%3A%22Me%20Raj%20K%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767067649%22%7D%5D%2C%22grSensitive%22%3Afalse%2C%22showResearch%22%3Afalse%2C%22blockVisibility%22%3A%7B%22hotBoard%22%3Atrue%2C%22hotVideo%22%3Atrue%2C%22relatedRecommend%22%3Atrue%7D%2C%22isGreyTheme%22%3Afalse%2C%22activateConfig%22%3A%7B%22enable%22%3Atrue%2C%22bannerInfo%22%3A%7B%22title%22%3A%22%E6%89%AB%E7%A0%81%E4%B8%8B%E8%BD%BD%E4%BB%8A%E6%97%A5%E5%A4%B4%E6%9D%A1APP%22%2C%22desc%22%3A%22%E7%9C%8B%E6%9C%80%E6%96%B0%E3%80%81%E6%9C%80%E7%83%AD%E8%B5%84%E8%AE%AF%E5%86%85%E5%AE%B9%22%2C%22qrcodeUrl%22%3A%22https%3A%2F%2Flf3-static.bytednsdoc.com%2Fobj%2Feden-cn%2Fbeeh7nuvjvho%2Fqrcode.png%22%7D%2C%22popupInfo%22%3A%7B%22title%22%3A%22%E6%89%AB%E7%A0%81%E4%B8%8B%E8%BD%BD%E4%BB%8A%E6%97%A5%E5%A4%B4%E6%9D%A1%22%2C%22qrcodeUrl%22%3A%22https%3A%2F%2Flf3-static.bytednsdoc.com%2Fobj%2Feden-cn%2Fbeeh7nuvjvho%2Fqrcode.png%22%7D%2C%22toolPopConfig%22%3A%7B%22permanent%22%3Atrue%7D%7D%2C%22searchBot%22%3Anull%2C%22commentInfo%22%3Anull%2C%22detailHotList%22%3Anull%2C%22detailFeedList%22%3Anull%7D%7D
reg := regexp.MustCompile(pattern) return reg.MatchString(username) } // 检查用户邮箱是否非法 func checkEmail(email string) bool { const pattern = `^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+​手把手教你如何进行 Golang 单元测试 - 今日头条{"@context":"https://schema.org","@type":"NewsArticle","mainEntityOfPage":{"@type":"WebPage","@id":"https://www.toutiao.com/article/7194623951715303970/"},"headline":"​手把手教你如何进行 Golang 单元测试","description":"引入随着工程化开发的内大力的推广,单元测试越来越受到广大开发者的重视。在学习的过程中,发现网上针对 Golang 单元测试大多从理论角度出发介绍,缺乏完整的实例说明,晦涩难懂的 API 让初学接触者难以下手。","image":["https://www.7claw.com/wp-content/uploads/2024/12/1734005244579_0.jpg","https://p3-sign.toutiaoimg.com/tos-cn-i-qvj2lq49k0/2f1220bbf1064c8a9eb83d7188697332~tplv-tt-origin-web:gif.jpeg?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1734609857&x-signature=6LvsZwDUwu%2BW76ZO0A0u9onC%2BDQ%3D","https://p3-sign.toutiaoimg.com/tos-cn-i-qvj2lq49k0/4f76255f3b074051aac9d049e5fe72ea~tplv-tt-origin-web:gif.jpeg?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1734609857&x-signature=HmsxOGVN213kq4mh2c3SQZOiCLQ%3D"],"datePublished":"2023-01-31T10:22:32+08:00","dateModified":"2024-11-23T01:11:32+08:00","author":{"@type":"Person","name":"Freemen程序员招聘app","url":"https://www.toutiao.com/c/user/token/MS4wLjABAAAAJOciZkc9eBL9yaD0sqJ6EvcVuBksXQMzilpmr2mk6bGNzfFMOA1wkQR9ctLoqvqA/"},"publisher":{"@type":"Organization","name":"今日头条","url":"https://www.toutiao.com/","logo":{"@type":"ImageObject","url":"https://lf3-static.bytednsdoc.com/obj/eden-cn/uhbfnupkbps/216.png"}}}!function(r,e,t,n,s,a,o,i,c,l,d,p,m,f){a="precollect",o="getAttribute",i="addEventListener",(l=function(e){(d=[].slice.call(arguments)).push(Date.now(),location.href),(e==a?l.p.a:l.q).push(d)}).q=[],l.p={a:[]},r[s]=l,(p=document.createElement("script")).src=t+"?bid=toutiao_web_pc&globalName="+s,p.crossOrigin=0<t.indexOf("sdk-web")?"anonymous":"use-credentials",e.getElementsByTagName("head")[0].appendChild(p),i in r&&(l.pcErr=function(e){e=e||r.event,(m=e.target||e.srcElement)instanceof Element||m instanceof HTMLElement?m[o]("integrity")?r[s](a,"sri",m[o]("href")||m[o]("src")):r[s](a,"st",{tagName:m.tagName,url:m[o]("href")||m[o]("src")}):r[s](a,"err",e.error||e.message)},l.pcRej=function(e){e=e||r.event,r[s](a,"err",e.reason||e.detail&&e.detail.reason)},r[i]("error",l.pcErr,!0),r[i]("unhandledrejection",l.pcRej,!0)),"PerformanceLongTaskTiming"in r&&((f=l.pp={entries:[]}).observer=new PerformanceObserver(function(e){f.entries=f.entries.concat(e.getEntries())}),f.observer.observe({entryTypes:["longtask","largest-contentful-paint","layout-shift"]}))}(window,document,"https://lf3-short.ibytedapm.com/slardar/fe/sdk-web/browser.cn.js",0,"Slardar")window.Slardar&&window.Slardar("init",{bid:"toutiao_web_pc",pid:"news_article_detail",release:"1.0.0.2328",env:"online",sample:{sample_rate:1},plugins:{ajax:{ignoreUrls:["mcs.snssdk.com","mcs.zijieapi.com","i.snssdk.com","verify.snssdk.com","vcs.snssdk.com","mon.zijieapi.com","mon.snssdk.com"]},pageview:{routeMode:"manual"},blankScreen:{rootSelector:"#root"}}})!function(n,t){if(n.LogAnalyticsObject=t,!n[t]){function c(){c.q.push(arguments)}c.q=c.q||[],n[t]=c}n[t].l=+new Date}(window,"collectEvent")window.collectEvent("usePlugin","autotrack"),window.collectEvent("usePlugin","stay"),window.collectEvent("init",{app_id:24,channel:"cn",autotrack:{custom:"tea",text:!0},enable_stay_duration:!0}),window.collectEvent("config",{evtParams:{url:window.location.href,screen_width:window.screen.width,screen_height:window.screen.height,screen_inner_width:window.innerWidth,screen_inner_height:window.innerHeight}})window.byted_acrawler&&window.byted_acrawler.init({aid:24,dfp:!0})!function(){var a="24",r="6457";var n=function(e,t,n){if(Math.ceil(100*Math.random())<=100*t){var o={ev_type:"batch",list:[{ev_type:"custom",payload:{name:"sdk_glue_load",type:"event",metrics:{},categories:{sdk_glue_load_status:e,sdk_glue_load_err_src:n,payload_bdms_aid:a,payload_bdms_page_id:r}},common:{context:{ctx_bdms_aid:a,ctx_bdms_page_id:r},bid:"web_bdms_cn",pid:window.location.pathname,view_id:"/_1",user_id:"",session_id:"0-a-1-2-c",release:"",env:"production",url:window.location.href,timestamp:+new Date,sdk_version:"1.6.1",sdk_name:"SDK_SLARDAR_WEB"}}]},i=new XMLHttpRequest;i.open("POST","https://mon.zijieapi.com/monitor_browser/collect/batch/?biz_id=web_bdms_cn",!0),i.setRequestHeader("Content-type","application/json"),i.send(JSON.stringify(o))}};!function(){try{(function(){try{var e="gfkadpd",t="24,"+r,n=function(e){for(var t=document.cookie.split(";"),n=0;n<t.length;n++){var o=t[n].trim();if(o.startsWith(e+"="))return o.substring(e.length+1)}return null}(e);if(n){if(-1!=n.indexOf(t))return;t+="|"+n}document.cookie=e+"="+t+"; expires="+new Date((new Date).getTime()+2592e5).toUTCString()+"; path=/; SameSite=None; Secure;"}catch(e){}})(),document.cookie="wdglgl=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/;",n("before_load",.1,"")}catch(e){}window.addEventListener("error",function(e){try{var t=e.target||e.srcElement;t instanceof HTMLElement&&"SCRIPT"==t.nodeName&&-1!=(t.src||"").indexOf("sdk-glue")&&(document.cookie="wdglgl=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/;",document.cookie="wdglgl="+(new Date).getTime()+"; expires="+new Date((new Date).getTime()+2592e5).toUTCString()+"; path=/; SameSite=None; Secure;",n("load_error",1,t.src))}catch(e){}},!0)}()}()window._SdkGlueInit&&window._SdkGlueInit({self:{aid:24,pageId:6457},bdms:{aid:24,pageId:6457,paths:["/api/pc/list/feed","/api/pc/list/user/feed"]}})window.TTGCaptcha&&window.TTGCaptcha.init({commonOptions:{aid:24,iid:"0",did:"0"}})window.secsdk&&window.secsdk.csrf.setProtectedHost({"www.toutiao.com":{GET:[],POST:[/^/api/pc/user/fans_digg/,/^/api/pc/user/delete/,/^/api/pc/user/follow/,/^/c/ugc/content/repost/,/^/group/repin/,/^/group/unrepin/,/^/api/pc/user/stick/,/^/api/pc/user/unstick/,/^/c/user/unfollow/,/^/wenda/v5/interact/followanswer/,/^/wenda/v5/interact/followquestion/,/^/wenda/v5/interact/digganswer/,/^/wenda/v5/interact/deleteanswer/,/^/user_data/batch_action/,/^/action/api/v1/do_action/],PUT:[],PATCH:[],DELETE:[]}})"undefined"!=typeof window&&"serviceWorker"in navigator&&window.addEventListener("load",function(){navigator.serviceWorker.register("/sw.js").catch(function(e){window.Slardar&&window.Slardar("emit","counter",{name:"sw-register-error",value:1})})})function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-QEHZPBE5HH")%7B%22data%22%3A%7B%22title%22%3A%22%E2%80%8B%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%20Golang%20%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%22%2C%22abstract%22%3A%22%E5%BC%95%E5%85%A5%E9%9A%8F%E7%9D%80%E5%B7%A5%E7%A8%8B%E5%8C%96%E5%BC%80%E5%8F%91%E7%9A%84%E5%86%85%E5%A4%A7%E5%8A%9B%E7%9A%84%E6%8E%A8%E5%B9%BF%EF%BC%8C%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%B6%8A%E6%9D%A5%E8%B6%8A%E5%8F%97%E5%88%B0%E5%B9%BF%E5%A4%A7%E5%BC%80%E5%8F%91%E8%80%85%E7%9A%84%E9%87%8D%E8%A7%86%E3%80%82%E5%9C%A8%E5%AD%A6%E4%B9%A0%E7%9A%84%E8%BF%87%E7%A8%8B%E4%B8%AD%EF%BC%8C%E5%8F%91%E7%8E%B0%E7%BD%91%E4%B8%8A%E9%92%88%E5%AF%B9%20Golang%20%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E5%A4%A7%E5%A4%9A%E4%BB%8E%E7%90%86%E8%AE%BA%E8%A7%92%E5%BA%A6%E5%87%BA%E5%8F%91%E4%BB%8B%E7%BB%8D%EF%BC%8C%E7%BC%BA%E4%B9%8F%E5%AE%8C%E6%95%B4%E7%9A%84%E5%AE%9E%E4%BE%8B%E8%AF%B4%E6%98%8E%EF%BC%8C%E6%99%A6%E6%B6%A9%E9%9A%BE%E6%87%82%E7%9A%84%20API%20%E8%AE%A9%E5%88%9D%E5%AD%A6%E6%8E%A5%E8%A7%A6%E8%80%85%E9%9A%BE%E4%BB%A5%E4%B8%8B%E6%89%8B%E3%80%82%22%2C%22articleType%22%3A%22article%22%2C%22itemId%22%3A%227194623951715303970%22%2C%22groupId%22%3A%227194623951715303970%22%2C%22groupSource%22%3A2%2C%22isOriginal%22%3Afalse%2C%22banComment%22%3Afalse%2C%22publishTime%22%3A%222023-01-31%2010%3A22%22%2C%22source%22%3A%22Freemen%E7%A8%8B%E5%BA%8F%E5%91%98%E6%8B%9B%E8%81%98app%22%2C%22tag%22%3A%22technique%22%2C%22mediaSite%22%3Anull%2C%22pathname%22%3A%22%2Farticle%2F7194623951715303970%2F%22%2C%22useCandle%22%3Afalse%2C%22isExclusive%22%3Afalse%2C%22favorite%22%3Afalse%2C%22relation%22%3A%7B%22isFollowing%22%3Afalse%2C%22isFollowed%22%3Afalse%7D%2C%22likeData%22%3A%7B%22userLikeStatus%22%3A0%2C%22count%22%3A76%7D%2C%22isSelf%22%3Afalse%2C%22content%22%3A%22%3Ch1%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%222%5C%22%3E%E5%BC%95%E5%85%A5%3C%2Fh1%3E%3Cp%20data-track%3D%5C%223%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E9%9A%8F%E7%9D%80%E5%B7%A5%E7%A8%8B%E5%8C%96%E5%BC%80%E5%8F%91%E7%9A%84%E5%86%85%E5%A4%A7%E5%8A%9B%E7%9A%84%E6%8E%A8%E5%B9%BF%EF%BC%8C%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%B6%8A%E6%9D%A5%E8%B6%8A%E5%8F%97%E5%88%B0%E5%B9%BF%E5%A4%A7%E5%BC%80%E5%8F%91%E8%80%85%E7%9A%84%E9%87%8D%E8%A7%86%E3%80%82%E5%9C%A8%E5%AD%A6%E4%B9%A0%E7%9A%84%E8%BF%87%E7%A8%8B%E4%B8%AD%EF%BC%8C%E5%8F%91%E7%8E%B0%E7%BD%91%E4%B8%8A%E9%92%88%E5%AF%B9%20Golang%20%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E5%A4%A7%E5%A4%9A%E4%BB%8E%E7%90%86%E8%AE%BA%E8%A7%92%E5%BA%A6%E5%87%BA%E5%8F%91%E4%BB%8B%E7%BB%8D%EF%BC%8C%E7%BC%BA%E4%B9%8F%E5%AE%8C%E6%95%B4%E7%9A%84%E5%AE%9E%E4%BE%8B%E8%AF%B4%E6%98%8E%EF%BC%8C%E6%99%A6%E6%B6%A9%E9%9A%BE%E6%87%82%E7%9A%84%20API%20%E8%AE%A9%E5%88%9D%E5%AD%A6%E6%8E%A5%E8%A7%A6%E8%80%85%E9%9A%BE%E4%BB%A5%E4%B8%8B%E6%89%8B%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%224%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%9C%AC%E7%AF%87%E4%B8%8D%E5%87%86%E5%A4%87%E5%A4%A7%E8%80%8C%E5%85%A8%E7%9A%84%E8%B0%88%E8%AE%BA%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E3%80%81%E7%AC%BC%E7%BB%9F%E7%9A%84%E4%BB%8B%E7%BB%8D%20Golang%20%E7%9A%84%E5%8D%95%E6%B5%8B%E5%B7%A5%E5%85%B7%EF%BC%8C%E8%80%8C%E5%B0%86%E4%BB%8E%20Golang%20%E5%8D%95%E6%B5%8B%E7%9A%84%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF%E5%87%BA%E5%8F%91%EF%BC%8C%E4%BB%A5%E6%9C%80%E7%AE%80%E5%8D%95%E4%B8%94%E5%AE%9E%E9%99%85%E7%9A%84%E4%BE%8B%E5%AD%90%E8%AE%B2%E8%A7%A3%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%E5%8D%95%E6%B5%8B%EF%BC%8C%E6%9C%80%E7%BB%88%E7%94%B1%E6%B5%85%E5%85%A5%E6%B7%B1%E6%8E%A2%E8%AE%A8%20go%20%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E4%B8%A4%E4%B8%AA%E6%AF%94%E8%BE%83%E7%BB%86%E8%8A%82%E7%9A%84%E9%97%AE%E9%A2%98%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%225%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9C%A8%E9%98%85%E8%AF%BB%E6%9C%AC%E6%96%87%E6%97%B6%EF%BC%8C%E8%AF%B7%E5%8A%A1%E5%BF%85%E5%AF%B9%20Golang%20%E7%9A%84%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E6%9C%89%E6%9C%80%E5%9F%BA%E6%9C%AC%E7%9A%84%E4%BA%86%E8%A7%A3%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Ch1%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%226%5C%22%3E%E4%B8%80%E6%AE%B5%E9%9C%80%E8%A6%81%E5%8D%95%E6%B5%8B%E7%9A%84%20Golang%20%E4%BB%A3%E7%A0%81%3C%2Fh1%3E%3Cpre%3E%3Ccode%3Epackage%20unit%5Cn%5Cnimport%20(%5Cn%20%26%2334%3Bencoding%2Fjson%26%2334%3B%5Cn%20%26%2334%3Berrors%26%2334%3B%5Cn%20%26%2334%3Bgithub.com%2Fgomodule%2Fredigo%2Fredis%26%2334%3B%5Cn%20%26%2334%3Bregexp%26%2334%3B%5Cn)%5Cn%5Cntype%20PersonDetail%20struct%20%7B%5Cn%20Username%20string%20%60json%3A%26%2334%3Busername%26%2334%3B%60%5Cn%20Email%20%20%20%20string%20%60json%3A%26%2334%3Bemail%26%2334%3B%60%5Cn%7D%5Cn%5Cn%2F%2F%20%E6%A3%80%E6%9F%A5%E7%94%A8%E6%88%B7%E5%90%8D%E6%98%AF%E5%90%A6%E9%9D%9E%E6%B3%95%5Cnfunc%20checkUsername(username%20string)%20bool%20%7B%5Cn%20const%20pattern%20%3D%20%60%5E%5Ba-z0-9_-%5D%7B3%2C16%7D%24%60%5Cn%5Cn%20reg%20%3A%3D%20regexp.MustCompile(pattern)%5Cn%20return%20reg.MatchString(username)%5Cn%7D%5Cn%5Cn%2F%2F%20%E6%A3%80%E6%9F%A5%E7%94%A8%E6%88%B7%E9%82%AE%E7%AE%B1%E6%98%AF%E5%90%A6%E9%9D%9E%E6%B3%95%5Cnfunc%20checkEmail(email%20string)%20bool%20%7B%5Cn%20const%20pattern%20%3D%20%60%5E%5Ba-zA-Z0-9_-%5D%2B%40%5Ba-zA-Z0-9_-%5D%2B(%5C%5C.%5Ba-zA-Z0-9_-%5D%2B)%2B%24%60%5Cn%5Cn%20reg%20%3A%3D%20regexp.MustCompile(pattern)%5Cn%20return%20reg.MatchString(email)%5Cn%7D%5Cn%5Cn%2F%2F%20%E9%80%9A%E8%BF%87%20redis%20%E6%8B%89%E5%8F%96%E5%AF%B9%E5%BA%94%E7%94%A8%E6%88%B7%E7%9A%84%E8%B5%84%E6%96%99%E4%BF%A1%E6%81%AF%5Cnfunc%20getPersonDetailRedis(username%20string)%20(*PersonDetail%2C%20error)%20%7B%5Cn%20result%20%3A%3D%20%26PersonDetail%7B%7D%5Cn%5Cn%20client%2C%20err%20%3A%3D%20redis.Dial(%26%2334%3Btcp%26%2334%3B%2C%20%26%2334%3B%3A6379%26%2334%3B)%5Cn%20defer%20client.Close()%5Cn%20data%2C%20err%20%3A%3D%20redis.Bytes(client.Do(%26%2334%3BGET%26%2334%3B%2C%20username))%5Cn%5Cn%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20return%20nil%2C%20err%5Cn%20%7D%5Cn%5Cn%20err%20%3D%20json.Unmarshal(data%2C%20result)%5Cn%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20return%20nil%2C%20err%5Cn%20%7D%5Cn%5Cn%20return%20result%2C%20nil%5Cn%7D%5Cn%5Cn%2F%2F%20%E6%8B%89%E5%8F%96%E7%94%A8%E6%88%B7%E8%B5%84%E6%96%99%E4%BF%A1%E6%81%AF%E5%B9%B6%E6%A0%A1%E9%AA%8C%5Cnfunc%20GetPersonDetail(username%20string)%20(*PersonDetail%2C%20error)%20%7B%5Cn%20%2F%2F%20%E6%A3%80%E6%9F%A5%E7%94%A8%E6%88%B7%E5%90%8D%E6%98%AF%E5%90%A6%E6%9C%89%E6%95%88%5Cn%20if%20ok%20%3A%3D%20checkUsername(username)%3B%20!ok%20%7B%5Cn%20%20return%20nil%2C%20errors.New(%26%2334%3Binvalid%20username%26%2334%3B)%5Cn%20%7D%5Cn%5Cn%20%2F%2F%20%E4%BB%8E%20redis%20%E6%8E%A5%E5%8F%A3%E8%8E%B7%E5%8F%96%E4%BF%A1%E6%81%AF%5Cn%20detail%2C%20err%20%3A%3D%20getPersonDetailRedis(username)%5Cn%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20return%20nil%2C%20err%5Cn%20%7D%5Cn%5Cn%20%2F%2F%20%E6%A0%A1%E9%AA%8C%5Cn%20if%20ok%20%3A%3D%20checkEmail(detail.Email)%3B%20!ok%20%7B%5Cn%20%20return%20nil%2C%20errors.New(%26%2334%3Binvalid%20email%26%2334%3B)%5Cn%20%7D%5Cn%5Cn%20return%20detail%2C%20nil%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%228%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%BF%99%E6%98%AF%E4%B8%80%E6%AE%B5%E5%85%B8%E5%9E%8B%E7%9A%84%E6%9C%89%20I%2FO%20%E7%9A%84%E5%8A%9F%E8%83%BD%E4%BB%A3%E7%A0%81%EF%BC%8C%E4%B8%BB%E4%BD%93%E5%8A%9F%E8%83%BD%E6%98%AF%E4%BC%A0%E5%85%A5%E7%94%A8%E6%88%B7%E5%90%8D%EF%BC%8C%E6%A0%A1%E9%AA%8C%E5%90%88%E6%B3%95%E6%80%A7%E4%B9%8B%E5%90%8E%E9%80%9A%E8%BF%87%20redis%20%E8%8E%B7%E5%8F%96%E4%BF%A1%E6%81%AF%EF%BC%8C%E4%B9%8B%E5%90%8E%E6%A0%A1%E9%AA%8C%E8%8E%B7%E5%8F%96%E5%80%BC%E5%86%85%E5%AE%B9%E7%9A%84%E5%90%88%E6%B3%95%E6%80%A7%E5%90%8E%E5%B9%B6%E8%BF%94%E5%9B%9E%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Ch1%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%229%5C%22%3E%E5%90%8E%E5%8F%B0%E6%9C%8D%E5%8A%A1%E5%8D%95%E6%B5%8B%E5%9C%BA%E6%99%AF%3C%2Fh1%3E%3Cp%20data-track%3D%5C%2210%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AF%B9%E4%BA%8E%E4%B8%80%E4%B8%AA%E4%BC%A0%E7%BB%9F%E7%9A%84%E5%90%8E%E7%AB%AF%E6%9C%8D%E5%8A%A1%EF%BC%8C%E5%AE%83%E4%B8%BB%E8%A6%81%E6%9C%89%E4%BB%A5%E4%B8%8B%E5%87%A0%E7%82%B9%E7%9A%84%E8%81%8C%E8%B4%A3%E5%92%8C%E5%8A%9F%E8%83%BD%EF%BC%9A%3C%2Fspan%3E%3C%2Fp%3E%3Cul%3E%3Cli%20data-track%3D%5C%2211%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%8E%A5%E6%94%B6%E5%A4%96%E9%83%A8%E8%AF%B7%E6%B1%82%EF%BC%8Ccontroller%20%E5%B1%82%E5%88%86%E5%8F%91%E8%AF%B7%E6%B1%82%E3%80%81%E6%A0%A1%E9%AA%8C%E8%AF%B7%E6%B1%82%E5%8F%82%E6%95%B0%3C%2Fspan%3E%3C%2Fli%3E%3Cli%20data-track%3D%5C%2212%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%AF%B7%E6%B1%82%E6%9C%89%E6%95%88%E5%88%86%E5%8F%91%E5%90%8E%EF%BC%8C%E5%9C%A8%20service%20%E5%B1%82%E4%B8%8E%20dao%20%E5%B1%82%E8%BF%9B%E8%A1%8C%E4%BA%A4%E4%BA%92%E5%90%8E%E5%81%9A%E9%80%BB%E8%BE%91%E5%A4%84%E7%90%86%3C%2Fspan%3E%3C%2Fli%3E%3Cli%20data-track%3D%5C%2213%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3Edao%20%E5%B1%82%E8%B4%9F%E8%B4%A3%E6%95%B0%E6%8D%AE%E6%93%8D%E4%BD%9C%EF%BC%8C%E4%B8%BB%E8%A6%81%E6%98%AF%E6%95%B0%E6%8D%AE%E5%BA%93%E6%88%96%E6%8C%81%E4%B9%85%E5%8C%96%E5%AD%98%E5%82%A8%E7%9B%B8%E5%85%B3%E7%9A%84%E6%93%8D%E4%BD%9C%3C%2Fspan%3E%3C%2Fli%3E%3C%2Ful%3E%3Cp%20data-track%3D%5C%2214%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9B%A0%E6%AD%A4%EF%BC%8C%E4%BB%8E%E8%81%8C%E8%B4%A3%E5%87%BA%E5%8F%91%E6%9D%A5%E7%9C%8B%EF%BC%8C%E5%9C%A8%E5%81%9A%E5%90%8E%E5%8F%B0%E5%8D%95%E6%B5%8B%E4%B8%AD%EF%BC%8C%E6%A0%B8%E5%BF%83%E4%B8%BB%E8%A6%81%E6%98%AF%E9%AA%8C%E8%AF%81%20service%20%E5%B1%82%E5%92%8C%20dao%20%E5%B1%82%E7%9A%84%E7%9B%B8%E5%85%B3%E9%80%BB%E8%BE%91%EF%BC%8C%E6%AD%A4%E5%A4%96%20controller%20%E5%B1%82%E7%9A%84%E5%8F%82%E6%95%B0%E6%A0%A1%E9%AA%8C%E4%B9%9F%E5%9C%A8%E5%8D%95%E6%B5%8B%E4%B9%8B%E4%B8%AD%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2215%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%BB%86%E5%88%86%E6%9D%A5%E7%9C%8B%EF%BC%8C%E5%AF%B9%E4%BA%8E%E7%9B%B8%E5%85%B3%E9%80%BB%E8%BE%91%E7%9A%84%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%EF%BC%8C%E7%AC%94%E8%80%85%E5%80%BE%E5%90%91%E4%BA%8E%E6%8A%8A%E5%8D%95%E6%B5%8B%E5%88%86%E4%B8%BA%E4%B8%A4%E7%A7%8D%EF%BC%9A%3C%2Fspan%3E%3C%2Fp%3E%3Cul%3E%3Cli%20data-track%3D%5C%2216%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%97%A0%E7%AC%AC%E4%B8%89%E6%96%B9%E4%BE%9D%E8%B5%96%EF%BC%8C%E7%BA%AF%E9%80%BB%E8%BE%91%E4%BB%A3%E7%A0%81%3C%2Fspan%3E%3C%2Fli%3E%3Cli%20data-track%3D%5C%2217%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%9C%89%E7%AC%AC%E4%B8%89%E6%96%B9%E4%BE%9D%E8%B5%96%EF%BC%8C%E5%A6%82%E6%96%87%E4%BB%B6%E3%80%81%E7%BD%91%E7%BB%9C%20I%2FO%E3%80%81%E7%AC%AC%E4%B8%89%E6%96%B9%E4%BE%9D%E8%B5%96%E5%BA%93%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93%E6%93%8D%E4%BD%9C%E7%9B%B8%E5%85%B3%E7%9A%84%E4%BB%A3%E7%A0%81%3C%2Fspan%3E%3C%2Fli%3E%3C%2Ful%3E%3Cp%20data-track%3D%5C%2218%5C%22%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%B3%A8%EF%BC%9A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%AD%E5%8F%AA%E6%98%AF%E9%92%88%E5%AF%B9%E5%8D%95%E4%B8%AA%E5%87%BD%E6%95%B0%E7%9A%84%E6%B5%8B%E8%AF%95%EF%BC%8C%E5%85%B3%E6%B3%A8%E5%85%B6%E5%86%85%E9%83%A8%E7%9A%84%E9%80%BB%E8%BE%91%EF%BC%8C%E5%AF%B9%E4%BA%8E%E7%BD%91%E7%BB%9C%2F%E6%95%B0%E6%8D%AE%E5%BA%93%E8%AE%BF%E9%97%AE%E7%AD%89%EF%BC%8C%E9%9C%80%E8%A6%81%E9%80%9A%E8%BF%87%E7%9B%B8%E5%BA%94%E7%9A%84%E6%89%8B%E6%AE%B5%E8%BF%9B%E8%A1%8C%20mock%E3%80%82%3C%2Fspan%3E%3C%2Fstrong%3E%3C%2Fp%3E%3Ch1%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2219%5C%22%3EGolang%20%E5%8D%95%E6%B5%8B%E5%B7%A5%E5%85%B7%E9%80%89%E5%9E%8B%3C%2Fh1%3E%3Cp%20data-track%3D%5C%2220%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%94%B1%E4%BA%8E%E6%88%91%E4%BB%AC%E6%8A%8A%E5%8D%95%E6%B5%8B%E7%AE%80%E5%8D%95%E7%9A%84%E5%88%86%E4%B8%BA%E4%BA%86%E4%B8%A4%E7%A7%8D%EF%BC%9A%3C%2Fspan%3E%3C%2Fp%3E%3Cul%3E%3Cli%20data-track%3D%5C%2221%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AF%B9%E4%BA%8E%E6%97%A0%E7%AC%AC%E4%B8%89%E6%96%B9%E4%BE%9D%E8%B5%96%E7%9A%84%E7%BA%AF%E9%80%BB%E8%BE%91%E4%BB%A3%E7%A0%81%EF%BC%8C%E6%88%91%E4%BB%AC%E5%8F%AA%E9%9C%80%E8%A6%81%E9%AA%8C%E8%AF%81%3C%2Fspan%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%9B%B8%E5%85%B3%E9%80%BB%E8%BE%91%3C%2Fspan%3E%3C%2Fstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%8D%B3%E5%8F%AF%EF%BC%8C%E8%BF%99%E9%87%8C%E5%8F%AA%E9%9C%80%E8%A6%81%E4%BD%BF%E7%94%A8%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Easser%3C%2Fspan%3E%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%231E6BB8%3B%5C%22%3Et%3C%2Fspan%3E%20%3Cstrong%3E%EF%BC%88%E6%96%AD%E8%A8%80%EF%BC%89%3C%2Fstrong%3E%EF%BC%8C%E9%80%9A%E8%BF%87%E6%8E%A7%E5%88%B6%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA%E6%AF%94%E5%AF%B9%E7%BB%93%E6%9E%9C%E5%8D%B3%E5%8F%AF%E3%80%82%3C%2Fli%3E%3Cli%20data-track%3D%5C%2222%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AF%B9%E4%BA%8E%E6%9C%89%E7%AC%AC%E4%B8%89%E6%96%B9%E4%BE%9D%E8%B5%96%E7%9A%84%E4%BB%A3%E7%A0%81%EF%BC%8C%E5%9C%A8%E9%AA%8C%E8%AF%81%E7%9B%B8%E5%85%B3%E4%BB%A3%E7%A0%81%E9%80%BB%E8%BE%91%E4%B9%8B%E5%89%8D%EF%BC%8C%E6%88%91%E4%BB%AC%E9%9C%80%E8%A6%81%E5%B0%86%E7%9B%B8%E5%85%B3%E7%9A%84%E4%BE%9D%E8%B5%96%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%20%3C%2Fspan%3E%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Emock%3C%2Fspan%3E%3C%2Fspan%3E%20%3Cstrong%3E%EF%BC%88%E6%A8%A1%E6%8B%9F%EF%BC%89%3C%2Fstrong%3E%EF%BC%8C%E4%B9%8B%E5%90%8E%E6%89%8D%E8%83%BD%E9%80%9A%E8%BF%87%E6%96%AD%E8%A8%80%E9%AA%8C%E8%AF%81%E9%80%BB%E8%BE%91%E3%80%82%E8%BF%99%E9%87%8C%E9%9C%80%E8%A6%81%E5%80%9F%E5%8A%A9%E7%AC%AC%E4%B8%89%E6%96%B9%E5%B7%A5%E5%85%B7%E5%BA%93%E6%9D%A5%E5%A4%84%E7%90%86%E3%80%82%3C%2Fli%3E%3C%2Ful%3E%3Cp%20data-track%3D%5C%2223%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9B%A0%E6%AD%A4%EF%BC%8C%E5%AF%B9%E4%BA%8E%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Eassert%3C%2Fspan%3E%3C%2Fspan%3E%20%3Cstrong%3E%EF%BC%88%E6%96%AD%E8%A8%80%EF%BC%89%3C%2Fstrong%3E%E5%B7%A5%E5%85%B7%EF%BC%8C%E5%8F%AF%E4%BB%A5%E9%80%89%E6%8B%A9%20testify%20%E6%88%96%20convery%EF%BC%8C%E7%AC%94%E8%80%85%E8%BF%99%E9%87%8C%E9%80%89%E6%8B%A9%E4%BA%86%20testify%E3%80%82%E5%AF%B9%E4%BA%8E%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Emock%3C%2Fspan%3E%3C%2Fspan%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%20%3C%2Fspan%3E%3Cstrong%3E%EF%BC%88%E6%A8%A1%E6%8B%9F%EF%BC%89%3C%2Fstrong%3E%E5%B7%A5%E5%85%B7%EF%BC%8C%E7%AC%94%E8%80%85%E8%BF%99%E9%87%8C%E9%80%89%E6%8B%A9%E4%BA%86%20gomock%20%E5%92%8C%20gomonkey%E3%80%82%E5%85%B3%E4%BA%8E%20mock%20%E5%B7%A5%E5%85%B7%E5%90%8C%E6%97%B6%E4%BD%BF%E7%94%A8%20gomock%20%E5%92%8C%20gomonkey%EF%BC%8C%E8%BF%99%E9%87%8C%E8%B7%9F%20Golang%20%E7%9A%84%E8%AF%AD%E8%A8%80%E7%89%B9%E6%80%A7%E6%9C%89%E5%85%B3%EF%BC%8C%E4%B8%8B%E9%9D%A2%E4%BC%9A%E8%AF%A6%E7%BB%86%E7%9A%84%E8%AF%B4%E6%98%8E%E3%80%82%3C%2Fp%3E%3Ch1%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2224%5C%22%3E%E5%AE%8C%E5%96%84%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B%3C%2Fh1%3E%3Cp%20data-track%3D%5C%2225%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%BF%99%E9%87%8C%E6%88%91%E4%BB%AC%E5%BC%80%E5%A7%8B%E5%AF%B9%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81%E4%B8%AD%E7%9A%84%E5%87%BD%E6%95%B0%E5%81%9A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2226%5C%22%3E%3Cspan%20style%3D%5C%22font-size%3A%201.118em%3B%5C%22%3E%3Cstrong%3E%E7%94%9F%E6%88%90%E5%8D%95%E6%B5%8B%E6%A8%A1%E6%9D%BF%E4%BB%A3%E7%A0%81%3C%2Fstrong%3E%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2227%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E9%A6%96%E5%85%88%E5%9C%A8%20Goland%20%E4%B8%AD%E6%89%93%E5%BC%80%E9%A1%B9%E7%9B%AE%EF%BC%8C%E5%8A%A0%E8%BD%BD%E5%AF%B9%E5%BA%94%E6%96%87%E4%BB%B6%E5%90%8E%E5%8F%B3%E9%94%AE%E6%89%BE%E5%88%B0%20Generate%20%E9%A1%B9%EF%BC%8C%E7%82%B9%E5%87%BB%E5%90%8E%E9%80%89%E6%8B%A9%20Tests%20for%20package%EF%BC%8C%E4%B9%8B%E5%90%8E%E7%94%9F%E6%88%90%E4%BB%A5%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E_test.go%3C%2Fspan%3E%3C%2Fspan%3E%20%E7%BB%93%E5%B0%BE%E7%9A%84%E5%8D%95%E6%B5%8B%E6%96%87%E4%BB%B6%E3%80%82%EF%BC%88%E5%A6%82%E6%9E%9C%E6%83%B3%E9%92%88%E5%AF%B9%E6%9F%90%E4%B8%80%E7%89%B9%E5%AE%9A%E5%87%BD%E6%95%B0%E5%81%9A%E5%8D%95%E6%B5%8B%EF%BC%8C%E8%AF%B7%E9%80%89%E6%8B%A9%E5%AF%B9%E5%BA%94%E7%9A%84%E5%87%BD%E6%95%B0%E5%90%8E%E5%8F%B3%E9%94%AE%E9%80%89%E5%AE%9A%20Generate%20%E9%A1%B9%E6%89%A7%E8%A1%8C%20Tests%20for%20selection%E3%80%82%EF%BC%89%3C%2Fp%3E%3Cp%20data-track%3D%5C%2228%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%BF%99%E9%87%8C%E5%B1%95%E7%A4%BA%E9%80%9A%E8%BF%87%20IDE%20%E7%94%9F%E6%88%90%E7%9A%84%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%20%3C%2Fspan%3E%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3ETestGetPersonDetail%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%B5%8B%E8%AF%95%E5%87%BD%E6%95%B0%EF%BC%9A%3C%2Fp%3E%3Cpre%3E%3Ccode%3Epackage%20unit%5Cn%5Cnimport%20(%5Cn%20%20%26%2334%3Breflect%26%2334%3B%5Cn%20%20%26%2334%3Btesting%26%2334%3B%5Cn)%5Cn%5Cnfunc%20TestGetPersonDetail(t%20*testing.T)%20%7B%5Cn%20type%20args%20struct%20%7B%5Cn%20%20username%20string%5Cn%20%7D%5Cn%20tests%20%3A%3D%20%5B%5Dstruct%20%7B%5Cn%20%20name%20%20%20%20string%5Cn%20%20args%20%20%20%20args%5Cn%20%20want%20%20%20%20*PersonDetail%5Cn%20%20wantErr%20bool%5Cn%20%7D%7B%5Cn%20%20%2F%2F%20TODO%3A%20Add%20test%20cases.%5Cn%20%7D%5Cn%20for%20_%2C%20tt%20%3A%3D%20range%20tests%20%7B%5Cn%20%20t.Run(tt.name%2C%20func(t%20*testing.T)%20%7B%5Cn%20%20%20got%2C%20err%20%3A%3D%20GetPersonDetail(tt.args.username)%5Cn%20%20%20if%20(err%20!%3D%20nil)%20!%3D%20tt.wantErr%20%7B%5Cn%20%20%20%20t.Errorf(%26%2334%3BGetPersonDetail()%20error%20%3D%20%25v%2C%20wantErr%20%25v%26%2334%3B%2C%20err%2C%20tt.wantErr)%5Cn%20%20%20%20return%5Cn%20%20%20%7D%5Cn%20%20%20if%20!reflect.DeepEqual(got%2C%20tt.want)%20%7B%5Cn%20%20%20%20t.Errorf(%26%2334%3BGetPersonDetail()%20got%20%3D%20%25v%2C%20want%20%25v%26%2334%3B%2C%20got%2C%20tt.want)%5Cn%20%20%20%7D%5Cn%20%20%7D)%5Cn%20%7D%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2230%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%94%B1%20Goland%20%E7%94%9F%E6%88%90%E7%9A%84%E5%8D%95%E6%B5%8B%E6%A8%A1%E6%9D%BF%E4%BB%A3%E7%A0%81%E4%BD%BF%E7%94%A8%E7%9A%84%E6%98%AF%E5%AE%98%E6%96%B9%E7%9A%84%20testing%20%E6%A1%86%E6%9E%B6%EF%BC%8C%E4%B8%BA%E4%BA%86%E6%9B%B4%E6%96%B9%E4%BE%BF%E7%9A%84%E6%96%AD%E8%A8%80%EF%BC%8C%E6%88%91%E4%BB%AC%E6%8A%8A%20testing%20%E6%94%B9%E9%80%A0%E6%88%90%20testify%20%E7%9A%84%E6%96%AD%E8%A8%80%E6%96%B9%E5%BC%8F%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2231%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%BF%99%E9%87%8C%E5%85%B6%E5%AE%9E%E5%8F%AA%E9%9C%80%E8%A6%81%E5%BC%95%E5%85%A5%20testify%20%E5%90%8E%E4%BF%AE%E6%94%B9%20test%20%E5%87%BD%E6%95%B0%E6%9C%80%E5%90%8E%E7%9A%84%E6%96%AD%E8%A8%80%E4%BB%A3%E7%A0%81%E5%8D%B3%E5%8F%AF%EF%BC%8C%E8%BF%99%E9%87%8C%E6%88%91%E4%BB%AC%E4%BB%A5%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3ETestGetPersonDetail%3C%2Fspan%3E%3C%2Fspan%3E%20%E4%B8%BA%E4%BE%8B%E5%AD%90%EF%BC%8C%E5%85%B6%E4%BB%96%E5%87%BD%E6%95%B0%E4%B8%8D%E8%B5%98%E8%BF%B0%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3Epackage%20unit%5Cnimport%20(%5Cn%20%20%26%2334%3Bgithub.com%2Fstretchr%2Ftestify%2Fassert%26%2334%3B%20%2F%2F%20%E8%BF%99%E9%87%8C%E5%BC%95%E5%85%A5%E4%BA%86%20testify%5Cn%20%20%26%2334%3Breflect%26%2334%3B%5Cn%20%20%26%2334%3Btesting%26%2334%3B%5Cn)%5Cn%5Cnfunc%20TestGetPersonDetail(t%20*testing.T)%20%7B%5Cn%20type%20args%20struct%20%7B%5Cn%20%20username%20string%5Cn%20%7D%5Cn%20tests%20%3A%3D%20%5B%5Dstruct%20%7B%5Cn%20%20name%20%20%20%20string%5Cn%20%20args%20%20%20%20args%5Cn%20%20want%20%20%20%20*PersonDetail%5Cn%20%20wantErr%20bool%5Cn%20%7D%7B%5Cn%20%20%2F%2F%20TODO%3A%20Add%20test%20cases.%5Cn%20%7D%5Cn%20for%20_%2C%20tt%20%3A%3D%20range%20tests%20%7B%5Cn%20%20got%2C%20err%20%3A%3D%20GetPersonDetail(tt.args.username)%5Cn%20%20%2F%2F%20%E6%94%B9%E5%86%99%E8%BF%99%E9%87%8C%E6%96%AD%E8%A8%80%E7%9A%84%E6%96%B9%E5%BC%8F%E5%8D%B3%E5%8F%AF%5Cn%20%20assert.Equal(t%2C%20tt.want%2C%20got)%5Cn%20%20assert.Equal(t%2C%20tt.wantErr%2C%20err%20!%3D%20nil)%5Cn%20%7D%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2233%5C%22%3E%3Cspan%20style%3D%5C%22font-size%3A%201.118em%3B%5C%22%3E%3Cstrong%3E%E5%88%86%E6%9E%90%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B%3C%2Fstrong%3E%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2234%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AF%B9%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EcheckUsername%3C%2Fspan%3E%3C%2Fspan%3E%20%E3%80%81%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EcheckEmail%3C%2Fspan%3E%3C%2Fspan%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%20%3C%2Fspan%3E%E7%BA%AF%E9%80%BB%E8%BE%91%E5%87%BD%E6%95%B0%E7%BC%96%E5%86%99%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B%EF%BC%8C%E8%BF%99%E9%87%8C%E4%BB%A5%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EcheckEmail%3C%2Fspan%3E%3C%2Fspan%3E%20%E4%B8%BA%E4%BE%8B%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3Efunc%20Test_checkEmail(t%20*testing.T)%20%7B%5Cn%20type%20args%20struct%20%7B%5Cn%20%20email%20string%5Cn%20%7D%5Cn%20tests%20%3A%3D%20%5B%5Dstruct%20%7B%5Cn%20%20name%20string%5Cn%20%20args%20args%5Cn%20%20want%20bool%5Cn%20%7D%7B%5Cn%20%20%7B%5Cn%20%20%20name%3A%20%26%2334%3Bemail%20valid%26%2334%3B%2C%5Cn%20%20%20args%3A%20args%7B%5Cn%20%20%20%20email%3A%20%26%2334%3B1234567%40qq.com%26%2334%3B%2C%5Cn%20%20%20%7D%2C%5Cn%20%20%20want%3A%20true%2C%5Cn%20%20%7D%2C%5Cn%20%20%7B%5Cn%20%20%20name%3A%20%26%2334%3Bemail%20invalid%26%2334%3B%2C%5Cn%20%20%20args%3A%20args%7B%5Cn%20%20%20%20email%3A%20%26%2334%3Btest.com%26%2334%3B%2C%5Cn%20%20%20%7D%2C%5Cn%20%20%20want%3A%20false%2C%5Cn%20%20%7D%2C%5Cn%20%7D%5Cn%20for%20_%2C%20tt%20%3A%3D%20range%20tests%20%7B%5Cn%20%20got%20%3A%3D%20checkEmail(tt.args.email)%5Cn%20%20assert.Equal(t%2C%20tt.want%2C%20got)%5Cn%20%7D%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2236%5C%22%3E%3Cspan%20style%3D%5C%22font-size%3A%201.118em%3B%5C%22%3E%3Cstrong%3E%E4%BD%BF%E7%94%A8%20gomonkey%20%E6%89%93%E6%A1%A9%3C%2Fstrong%3E%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2237%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AF%B9%E4%BA%8E%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EGetPersonDetail%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E8%80%8C%E8%A8%80%EF%BC%8C%E8%AF%A5%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E4%BA%86%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EgetPersonDetailRedis%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E8%8E%B7%E5%8F%96%E5%85%B7%E4%BD%93%E7%9A%84%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EPersonDetail%3C%2Fspan%3E%3C%2Fspan%3E%20%E4%BF%A1%E6%81%AF%E3%80%82%E4%B8%BA%E6%AD%A4%EF%BC%8C%E6%88%91%E4%BB%AC%E9%9C%80%E8%A6%81%E4%B8%BA%E5%AE%83%E6%89%93%E4%B8%80%E4%B8%AA%E2%80%9C%E6%A1%A9%E2%80%9D%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2238%5C%22%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%89%80%E8%B0%93%E7%9A%84%E2%80%9C%E6%A1%A9%E2%80%9D%EF%BC%8C%E4%B9%9F%E5%8F%AB%E5%81%9A%E2%80%9C%E6%A1%A9%E4%BB%A3%E7%A0%81%E2%80%9D%EF%BC%8C%E6%98%AF%E6%8C%87%E7%94%A8%E6%9D%A5%E4%BB%A3%E6%9B%BF%E5%85%B3%E8%81%94%E4%BB%A3%E7%A0%81%E6%88%96%E8%80%85%E6%9C%AA%E5%AE%9E%E7%8E%B0%E4%BB%A3%E7%A0%81%E7%9A%84%E4%BB%A3%E7%A0%81%E3%80%82%3C%2Fspan%3E%3C%2Fstrong%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2239%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AF%B9%E4%BA%8E%E5%87%BD%E6%95%B0%E3%80%81%E6%88%90%E5%91%98%E6%96%B9%E6%B3%95%E6%88%96%E8%80%85%E6%98%AF%E5%8F%98%E9%87%8F%E7%9A%84%E6%89%93%E6%A1%A9%EF%BC%8C%E6%88%91%E4%BB%AC%E9%80%9A%E5%B8%B8%E4%BD%BF%E7%94%A8%20gomonkey%20%E6%9D%A5%E8%BF%9B%E8%A1%8C%E6%89%93%E6%A1%A9%E3%80%82%E5%85%B7%E4%BD%93%20API%20%E8%AF%B7%E5%8F%82%E8%80%83%EF%BC%9Ahttps%3A%2F%2Fpkg.go.dev%2Fgithub.com%2Fagiledragon%2Fgomonkey%3C%2Fspan%3E%3C%2Fp%3E%3Cpre%3E%3Ccode%3E%2F%2F%20%E6%8B%89%E5%8F%96%E7%94%A8%E6%88%B7%E8%B5%84%E6%96%99%E4%BF%A1%E6%81%AF%E5%B9%B6%E6%A0%A1%E9%AA%8C%5Cnfunc%20GetPersonDetail(username%20string)%20(*PersonDetail%2C%20error)%20%7B%5Cn%20%2F%2F%20%E6%A3%80%E6%9F%A5%E7%94%A8%E6%88%B7%E5%90%8D%E6%98%AF%E5%90%A6%E6%9C%89%E6%95%88%5Cn%20if%20ok%20%3A%3D%20checkUsername(username)%3B%20!ok%20%7B%5Cn%20%20return%20nil%2C%20errors.New(%26%2334%3Binvalid%20username%26%2334%3B)%5Cn%20%7D%5Cn%5Cn%20%2F%2F%20%E4%BB%8E%20redis%20%E6%8E%A5%E5%8F%A3%E8%8E%B7%E5%8F%96%E4%BF%A1%E6%81%AF%5Cn%20detail%2C%20err%20%3A%3D%20getPersonDetailRedis(username)%5Cn%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20return%20nil%2C%20err%5Cn%20%7D%5Cn%5Cn%20%2F%2F%20%E6%A0%A1%E9%AA%8C%5Cn%20if%20ok%20%3A%3D%20checkEmail(detail.Email)%3B%20!ok%20%7B%5Cn%20%20return%20nil%2C%20errors.New(%26%2334%3Binvalid%20email%26%2334%3B)%5Cn%20%7D%5Cn%5Cn%20return%20detail%2C%20nil%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2241%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%BB%8E%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EGetPersonDetail%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E5%8F%AF%E8%A7%81%EF%BC%8C%E4%B8%BA%E4%BA%86%E8%83%BD%E5%A4%9F%E5%AE%8C%E5%85%A8%E8%A6%86%E7%9B%96%E8%AF%A5%E5%87%BD%E6%95%B0%EF%BC%8C%E6%88%91%E4%BB%AC%E9%9C%80%E8%A6%81%E6%8E%A7%E5%88%B6%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EgetPersonDetailRedis%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E4%B8%8D%E5%90%8C%E7%9A%84%E8%BE%93%E5%87%BA%E6%9D%A5%E4%BF%9D%E8%AF%81%E5%90%8E%E7%BB%AD%E4%BB%A3%E7%A0%81%E9%83%BD%E8%83%BD%E5%A4%9F%E8%A2%AB%E8%A6%86%E7%9B%96%E8%BF%90%E8%A1%8C%E5%88%B0%E3%80%82%E5%9B%A0%E6%AD%A4%EF%BC%8C%E8%BF%99%E9%87%8C%E9%9C%80%E8%A6%81%E4%BD%BF%E7%94%A8%20gomonkey%20%E6%9D%A5%E7%BB%99%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EgetPersonDetailRedis%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E6%89%93%E4%B8%80%E4%B8%AA%E2%80%9C%E6%A1%A9%E5%BA%8F%E5%88%97%E2%80%9D%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2242%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%89%80%E8%B0%93%E7%9A%84%E5%87%BD%E6%95%B0%E2%80%9C%E6%A1%A9%E5%BA%8F%E5%88%97%E2%80%9D%E6%8C%87%E7%9A%84%E6%98%AF%E6%8F%90%E5%89%8D%E6%8C%87%E5%AE%9A%E5%A5%BD%E8%B0%83%E7%94%A8%E5%87%BD%E6%95%B0%E7%9A%84%E8%BF%94%E5%9B%9E%E5%80%BC%E5%BA%8F%E5%88%97%EF%BC%8C%E5%BD%93%E8%AF%A5%E5%87%BD%E6%95%B0%E5%A4%9A%E6%AC%A1%E8%B0%83%E7%94%A8%E6%97%B6%E5%80%99%EF%BC%8C%E8%83%BD%E5%A4%9F%E6%8C%89%E7%85%A7%E5%8E%9F%E5%85%88%E6%8C%87%E5%AE%9A%E7%9A%84%E8%BF%94%E5%9B%9E%E5%80%BC%E5%BA%8F%E5%88%97%E4%BE%9D%E6%AC%A1%E8%BF%94%E5%9B%9E%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cpre%3E%3Ccode%3Efunc%20TestGetPersonDetail(t%20*testing.T)%20%7B%5Cn%20type%20args%20struct%20%7B%5Cn%20%20username%20string%5Cn%20%7D%5Cn%20tests%20%3A%3D%20%5B%5Dstruct%20%7B%5Cn%20%20name%20%20%20%20string%5Cn%20%20args%20%20%20%20args%5Cn%20%20want%20%20%20%20*PersonDetail%5Cn%20%20wantErr%20bool%5Cn%20%7D%7B%5Cn%20%20%7Bname%3A%20%26%2334%3Binvalid%20username%26%2334%3B%2C%20args%3A%20args%7Busername%3A%20%26%2334%3Bsteven%20xxx%26%2334%3B%7D%2C%20want%3A%20nil%2C%20wantErr%3A%20true%7D%2C%5Cn%20%20%7Bname%3A%20%26%2334%3Binvalid%20email%26%2334%3B%2C%20args%3A%20args%7Busername%3A%20%26%2334%3Binvalid_email%26%2334%3B%7D%2C%20want%3A%20nil%2C%20wantErr%3A%20true%7D%2C%5Cn%20%20%7Bname%3A%20%26%2334%3Bthrow%20err%26%2334%3B%2C%20args%3A%20args%7Busername%3A%20%26%2334%3Bthrow_err%26%2334%3B%7D%2C%20want%3A%20nil%2C%20wantErr%3A%20true%7D%2C%5Cn%20%20%7Bname%3A%20%26%2334%3Bvalid%20return%26%2334%3B%2C%20args%3A%20args%7Busername%3A%20%26%2334%3Bsteven%26%2334%3B%7D%2C%20want%3A%20%26PersonDetail%7BUsername%3A%20%26%2334%3Bsteven%26%2334%3B%2C%20Email%3A%20%26%2334%3B12345678%40qq.com%26%2334%3B%7D%2C%20wantErr%3A%20false%7D%2C%5Cn%20%7D%5Cn%5Cn%20%2F%2F%20%E4%B8%BA%E5%87%BD%E6%95%B0%E6%89%93%E6%A1%A9%E5%BA%8F%E5%88%97%5Cn%20%2F%2F%20%E4%BD%BF%E7%94%A8%20gomonkey%20%E6%89%93%E5%87%BD%E6%95%B0%E6%A1%A9%E5%BA%8F%E5%88%97%5Cn%20%2F%2F%20%E7%AC%AC%E4%B8%80%E4%B8%AA%E7%94%A8%E4%BE%8B%E4%B8%8D%E4%BC%9A%E8%B0%83%E7%94%A8%20getPersonDetailRedis%EF%BC%8C%E6%89%80%E4%BB%A5%E5%8F%AA%E9%9C%80%E8%A6%81%203%20%E4%B8%AA%E5%80%BC%5Cn%20outputs%20%3A%3D%20%5B%5Dgomonkey.OutputCell%7B%5Cn%20%20%7B%5Cn%20%20%20Values%3A%20gomonkey.Params%7B%26PersonDetail%7BUsername%3A%20%26%2334%3Binvalid_email%26%2334%3B%2C%20Email%3A%20%26%2334%3Btest.com%26%2334%3B%7D%2C%20nil%7D%2C%5Cn%20%20%7D%2C%5Cn%20%20%7B%5Cn%20%20%20Values%3A%20gomonkey.Params%7Bnil%2C%20errors.New(%26%2334%3Brequest%20err%26%2334%3B)%7D%2C%5Cn%20%20%7D%2C%5Cn%20%20%7B%5Cn%20%20%20Values%3A%20gomonkey.Params%7B%26PersonDetail%7BUsername%3A%20%26%2334%3Bsteven%26%2334%3B%2C%20Email%3A%20%26%2334%3B12345678%40qq.com%26%2334%3B%7D%2C%20nil%7D%2C%5Cn%20%20%7D%2C%5Cn%20%7D%5Cn%20patches%20%3A%3D%20gomonkey.ApplyFuncSeq(getPersonDetailRedis%2C%20outputs)%5Cn%20%2F%2F%20%E6%89%A7%E8%A1%8C%E5%AE%8C%E6%AF%95%E5%90%8E%E9%87%8A%E6%94%BE%E6%A1%A9%E5%BA%8F%E5%88%97%5Cn%20defer%20patches.Reset()%5Cn%5Cn%20for%20_%2C%20tt%20%3A%3D%20range%20tests%20%7B%5Cn%20%20got%2C%20err%20%3A%3D%20GetPersonDetail(tt.args.username)%5Cn%20%20assert.Equal(t%2C%20tt.want%2C%20got)%5Cn%20%20assert.Equal(t%2C%20tt.wantErr%2C%20err%20!%3D%20nil)%5Cn%20%7D%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2244%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%BD%93%E4%BD%BF%E7%94%A8%E6%A1%A9%E5%BA%8F%E5%88%97%E6%97%B6%EF%BC%8C%E8%A6%81%E5%88%86%E6%9E%90%E5%A5%BD%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B%E5%92%8C%E5%BA%8F%E5%88%97%E5%80%BC%E7%9A%84%E5%AF%B9%E5%BA%94%E5%85%B3%E7%B3%BB%EF%BC%8C%E4%BF%9D%E8%AF%81%E6%9C%80%E7%BB%88%E8%A2%AB%E6%B5%8B%E8%AF%95%E7%9A%84%E4%BB%A3%E7%A0%81%E5%9D%97%E9%83%BD%E8%83%BD%E8%A2%AB%E5%AE%8C%E6%95%B4%E8%A6%86%E7%9B%96%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2245%5C%22%3E%3Cspan%20style%3D%5C%22font-size%3A%201.118em%3B%5C%22%3E%3Cstrong%3E%E4%BD%BF%E7%94%A8%20gomock%20%E6%89%93%E6%A1%A9%3C%2Fstrong%3E%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2246%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%9C%80%E5%90%8E%E5%89%A9%E4%B8%8B%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EgetPersonDetailRedis%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%EF%BC%8C%E6%88%91%E4%BB%AC%E5%85%88%E6%9D%A5%E7%9C%8B%E4%B8%80%E4%B8%8B%E8%BF%99%E4%B8%AA%E5%87%BD%E6%95%B0%E7%9A%84%E9%80%BB%E8%BE%91%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3E%2F%2F%20%E9%80%9A%E8%BF%87%20redis%20%E6%8B%89%E5%8F%96%E5%AF%B9%E5%BA%94%E7%94%A8%E6%88%B7%E7%9A%84%E8%B5%84%E6%96%99%E4%BF%A1%E6%81%AF%5Cnfunc%20getPersonDetailRedis(username%20string)%20(*PersonDetail%2C%20error)%20%7B%5Cn%20result%20%3A%3D%20%26PersonDetail%7B%7D%5Cn%5Cn%20client%2C%20err%20%3A%3D%20redis.Dial(%26%2334%3Btcp%26%2334%3B%2C%20%26%2334%3B%3A6379%26%2334%3B)%5Cn%20defer%20client.Close()%5Cn%20data%2C%20err%20%3A%3D%20redis.Bytes(client.Do(%26%2334%3BGET%26%2334%3B%2C%20username))%5Cn%5Cn%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20return%20nil%2C%20err%5Cn%20%7D%5Cn%5Cn%20err%20%3D%20json.Unmarshal(data%2C%20result)%5Cn%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20return%20nil%2C%20err%5Cn%20%7D%5Cn%5Cn%20return%20result%2C%20nil%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2248%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EgetPersonDetailRedis%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E7%9A%84%E6%A0%B8%E5%BF%83%E5%9C%A8%E4%BA%8E%E7%94%9F%E6%88%90%E4%BA%86%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Eclient%3C%2Fspan%3E%3C%2Fspan%3E%20%E8%B0%83%E7%94%A8%E4%BA%86%E5%AE%83%E7%9A%84%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EDo%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%96%B9%E6%B3%95%EF%BC%8C%E9%80%9A%E8%BF%87%E5%88%86%E6%9E%90%E5%BE%97%E7%9F%A5%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Eclient%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%AE%9E%E9%99%85%E4%B8%8A%E6%98%AF%E4%B8%80%E4%B8%AA%E7%AC%A6%E5%90%88%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EConn%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%8E%A5%E5%8F%A3%E7%9A%84%E7%BB%93%E6%9E%84%E4%BD%93%E3%80%82%E5%A6%82%E6%9E%9C%E6%88%91%E4%BB%AC%E4%BD%BF%E7%94%A8%20gomonkey%20%E6%9D%A5%E8%BF%9B%E8%A1%8C%E6%89%93%E6%A1%A9%EF%BC%8C%E9%9C%80%E8%A6%81%E5%85%88%E5%A3%B0%E6%98%8E%E4%B8%80%E4%B8%AA%E7%BB%93%E6%9E%84%E4%BD%93%E5%B9%B6%E5%AE%9E%E7%8E%B0%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EClient%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%8E%A5%E5%8F%A3%E6%8B%A5%E6%9C%89%E7%9A%84%E6%96%B9%E6%B3%95%EF%BC%8C%E4%B9%8B%E5%90%8E%E6%89%8D%E8%83%BD%E4%BD%BF%E7%94%A8%20gomonkey%20%E7%BB%99%E5%87%BD%E6%95%B0%E6%89%93%E6%A1%A9%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3E%2F%2F%20redis%20%E5%8C%85%E4%B8%AD%E5%85%B3%E4%BA%8E%20Conn%20%E7%9A%84%E5%AE%9A%E4%B9%89%5Cn%2F%2F%20Conn%20represents%20a%20connection%20to%20a%20Redis%20server.%5Cntype%20Conn%20interface%20%7B%5Cn%20%2F%2F%20Close%20closes%20the%20connection.%5Cn%20Close()%20error%5Cn%5Cn%20%2F%2F%20Err%20returns%20a%20non-nil%20value%20when%20the%20connection%20is%20not%20usable.%5Cn%20Err()%20error%5Cn%5Cn%20%2F%2F%20Do%20sends%20a%20command%20to%20the%20server%20and%20returns%20the%20received%20reply.%5Cn%20Do(commandName%20string%2C%20args%20...interface%7B%7D)%20(reply%20interface%7B%7D%2C%20err%20error)%5Cn%5Cn%20%2F%2F%20Send%20writes%20the%20command%20to%20the%20client%26%2339%3Bs%20output%20buffer.%5Cn%20Send(commandName%20string%2C%20args%20...interface%7B%7D)%20error%5Cn%5Cn%20%2F%2F%20Flush%20flushes%20the%20output%20buffer%20to%20the%20Redis%20server.%5Cn%20Flush()%20error%5Cn%5Cn%20%2F%2F%20Receive%20receives%20a%20single%20reply%20from%20the%20Redis%20server%5Cn%20Receive()%20(reply%20interface%7B%7D%2C%20err%20error)%5Cn%7D%5Cn%5Cn%2F%2F%20%E5%AE%9E%E7%8E%B0%E6%8E%A5%E5%8F%A3%5Cntype%20Client%20struct%20%7B%7D%5Cnfunc%20(c%20*Client)%20Close()%20error%20%7B%5Cn%20%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Err()%20error%20%7B%5Cn%20%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Do(commandName%20string%2C%20args%20...interface%7B%7D)%20(interface%7B%7D%2C%20error)%20%7B%5Cn%20%20return%20nil%2C%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Send(commandName%20string%2C%20args%20...interface%7B%7D)%20error%20%7B%5Cn%20%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Flush()%20error%20%7B%5Cn%20%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Receive()%20(interface%7B%7D%2C%20error)%20%7B%5Cn%20%20return%20nil%2C%20nil%5Cn%7D%5Cn%5Cn%2F%2F%20%E5%AE%9E%E7%8E%B0%E6%8E%A5%E5%8F%A3%5Cntype%20Client%20struct%20%7B%7D%5Cnfunc%20(c%20*Client)%20Close()%20error%20%7B%5Cn%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Err()%20error%20%7B%5Cn%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Do(commandName%20string%2C%20args%20...interface%7B%7D)%20(interface%7B%7D%2C%20error)%20%7B%5Cn%20return%20nil%2C%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Send(commandName%20string%2C%20args%20...interface%7B%7D)%20error%20%7B%5Cn%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Flush()%20error%20%7B%5Cn%20return%20nil%5Cn%7D%5Cnfunc%20(c%20*Client)%20Receive()%20(interface%7B%7D%2C%20error)%20%7B%5Cn%20return%20nil%2C%20nil%5Cn%7D%5Cn%2F%2F%20%E8%BF%9B%E8%A1%8C%E6%B5%8B%E8%AF%95%5Cnfunc%20test()%20%7B%5Cn%20c%20%3A%3D%20%26Client%7B%7D%5Cn%20gomonkey.ApplyFunc(redis.Dial%2C%20func(_%20string%2C%20_%20string%2C%20_%20...redis.DialOption)%20(redis.Conn%2C%20error)%20%7B%5Cn%20%20return%20c%2C%20nil%5Cn%20%7D)%5Cn%20gomonkey.ApplyMethod(reflect.TypeOf(c)%2C%20%26%2334%3BDo%26%2334%3B%2C%20func(commandName%20string%2C%20args%20...interface%7B%7D)%20(interface%7B%7D%2C%20error)%20%7B%5Cn%20%20var%20result%20interface%7B%7D%5Cn%20%20return%20result%2C%20nil%5Cn%20%7D)%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2250%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%8F%AF%E8%A7%81%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%8E%A5%E5%8F%A3%E5%AE%9E%E7%8E%B0%E7%9A%84%E6%96%B9%E6%B3%95%E6%9B%B4%E5%A4%9A%EF%BC%8C%E9%82%A3%E4%B9%88%E6%89%93%E6%A1%A9%E9%9C%80%E8%A6%81%E6%89%8B%E5%86%99%E7%9A%84%E4%BB%A3%E7%A0%81%E4%BC%9A%E6%9B%B4%E5%A4%9A%E3%80%82%E5%9B%A0%E6%AD%A4%E8%BF%99%E9%87%8C%E9%9C%80%E8%A6%81%E4%B8%80%E7%A7%8D%E8%83%BD%E8%87%AA%E5%8A%A8%E6%A0%B9%E6%8D%AE%E5%8E%9F%E6%8E%A5%E5%8F%A3%E7%9A%84%E5%AE%9A%E4%B9%89%E7%94%9F%E6%88%90%E6%8E%A5%E5%8F%A3%E7%9A%84%20mock%20%E4%BB%A3%E7%A0%81%E4%BB%A5%E5%8F%8A%E6%9B%B4%E6%96%B9%E4%BE%BF%E7%9A%84%E6%8E%A5%E5%8F%A3%20mock%20%E6%96%B9%E5%BC%8F%E3%80%82%E4%BA%8E%E6%98%AF%E8%BF%99%E9%87%8C%E6%88%91%E4%BB%AC%E4%BD%BF%E7%94%A8%20gomock%20%E6%9D%A5%E8%A7%A3%E5%86%B3%E8%BF%99%E4%B8%AA%E9%97%AE%E9%A2%98%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2251%5C%22%3E%3Cstrong%3E%E6%9C%AC%E5%9C%B0%E5%AE%89%E8%A3%85%20gomock%3C%2Fstrong%3E%3C%2Fp%3E%3Cpre%3E%3Ccode%3E%23%20%E6%89%93%E5%BC%80%E7%BB%88%E7%AB%AF%E5%90%8E%E4%BE%9D%E6%AC%A1%E6%89%A7%E8%A1%8C%5Cngo%20get%20-u%20github.com%2Fgolang%2Fmock%2Fgomock%5Cngo%20install%20github.com%2Fgolang%2Fmock%2Fmockgen%5Cn%23%20%E5%A4%87%E6%B3%A8%E8%AF%B4%E6%98%8E%EF%BC%8C%E5%BE%88%E9%87%8D%E8%A6%81%EF%BC%81%EF%BC%81%EF%BC%81%5Cn%23%20%E5%AE%89%E8%A3%85%E5%AE%8C%E6%88%90%E4%B9%8B%E5%90%8E%EF%BC%8C%E6%89%A7%E8%A1%8C%20mockgen%20%E7%9C%8B%E5%91%BD%E4%BB%A4%E6%98%AF%E5%90%A6%E7%94%9F%E6%95%88%20%23%20%E5%A6%82%E6%9E%9C%E6%98%BE%E7%A4%BA%E5%91%BD%E4%BB%A4%E6%97%A0%E6%95%88%EF%BC%8C%E8%AF%B7%E6%89%BE%E5%88%B0%E6%9C%AC%E6%9C%BA%E7%9A%84%20GOPATH%20%E5%AE%89%E8%A3%85%E7%9B%AE%E5%BD%95%E4%B8%8B%E7%9A%84%20bin%20%E6%96%87%E4%BB%B6%E5%A4%B9%E6%98%AF%E5%90%A6%E6%9C%89%20mockgen%20%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%96%87%E4%BB%B6%5Cn%23%20GOPATH%20%E5%8F%AF%E4%BB%A5%E6%89%A7%E8%A1%8C%20go%20env%20%E5%91%BD%E4%BB%A4%E6%89%BE%E5%88%B0%5Cn%23%20%E5%A6%82%E6%9E%9C%E5%91%BD%E4%BB%A4%E6%97%A0%E6%95%88%E4%BD%86%E6%98%AF%20GOPATH%20%E8%B7%AF%E5%BE%84%E4%B8%8B%E7%9A%84%20bin%20%E6%96%87%E4%BB%B6%E5%A4%B9%E4%B8%AD%E5%AD%98%E5%9C%A8%20mockgen%EF%BC%8C%E8%AF%B7%E5%B0%86%20GOPATH%20%E4%B8%8B%20bin%20%E6%96%87%E4%BB%B6%E5%A4%B9%E7%9A%84%E7%BB%9D%E5%AF%B9%E8%B7%AF%E5%BE%84%E6%B7%BB%E5%8A%A0%E5%88%B0%E5%85%A8%E5%B1%80%20PATH%20%E4%B8%AD%5Cn%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2253%5C%22%3E%3Cstrong%3E%E7%94%9F%E6%88%90%20gomock%20%E6%A1%A9%E4%BB%A3%E7%A0%81%3C%2Fstrong%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2254%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AE%89%E8%A3%85%E5%AE%8C%E6%AF%95%E5%90%8E%EF%BC%8C%E6%89%BE%E5%88%B0%E8%A6%81%E8%BF%9B%E8%A1%8C%E6%89%93%E6%A1%A9%E7%9A%84%E6%8E%A5%E5%8F%A3%EF%BC%8C%E8%BF%99%E9%87%8C%E6%98%AF%20github.com%2Fgomodule%2Fredigo%2Fredis%20%E5%8C%85%E9%87%8C%E9%9D%A2%E7%9A%84%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EConn%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%8E%A5%E5%8F%A3%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2255%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9C%A8%E5%BD%93%E5%89%8D%E4%BB%A3%E7%A0%81%E7%9B%AE%E5%BD%95%E4%B8%8B%E6%89%A7%E8%A1%8C%E4%BB%A5%E4%B8%8B%E6%8C%87%E4%BB%A4%EF%BC%8C%E8%BF%99%E9%87%8C%E6%88%91%E4%BB%AC%E5%8F%AA%E5%AF%B9%E6%9F%90%E4%B8%AA%E7%89%B9%E5%AE%9A%E7%9A%84%E6%8E%A5%E5%8F%A3%E7%94%9F%E6%88%90%20mock%20%E4%BB%A3%E7%A0%81%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cpre%3E%3Ccode%3Emockgen%20-destination%3Dmock_redis.go%20-package%3Dunit%20github.com%2Fgomodule%2Fredigo%2Fredis%20Conn%5Cn%23%20%E6%9B%B4%E5%A4%9A%E6%8C%87%E4%BB%A4%E5%8F%82%E8%80%83%EF%BC%9Ahttps%3A%2F%2Fgithub.com%2Fgolang%2Fmock%23flags%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2257%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%94%9F%E6%88%90%E7%9A%84%E4%BB%A3%E7%A0%81%E5%8F%82%E8%80%83%20mock_redis.go%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2258%5C%22%3E%3Cstrong%3E%E5%AE%8C%E5%96%84%20gomock%20%E7%9B%B8%E5%85%B3%E9%80%BB%E8%BE%91%3C%2Fstrong%3E%3C%2Fp%3E%3Cpre%3E%3Ccode%3Efunc%20Test_getPersonDetailRedis(t%20*testing.T)%20%7B%5Cn%20tests%20%3A%3D%20%5B%5Dstruct%20%7B%5Cn%20%20name%20%20%20%20string%5Cn%20%20want%20%20%20%20*PersonDetail%5Cn%20%20wantErr%20bool%5Cn%20%7D%7B%5Cn%20%20%7Bname%3A%20%26%2334%3Bredis.Do%20err%26%2334%3B%2C%20want%3A%20nil%2C%20wantErr%3A%20true%7D%2C%5Cn%20%20%7Bname%3A%20%26%2334%3Bjson.Unmarshal%20err%26%2334%3B%2C%20want%3A%20nil%2C%20wantErr%3A%20true%7D%2C%5Cn%20%20%7Bname%3A%20%26%2334%3Bsuccess%26%2334%3B%2C%20want%3A%20%26PersonDetail%7B%5Cn%20%20%20Username%3A%20%26%2334%3Bsteven%26%2334%3B%2C%5Cn%20%20%20Email%3A%20%20%20%20%26%2334%3B1234567%40qq.com%26%2334%3B%2C%5Cn%20%20%7D%2C%20wantErr%3A%20false%7D%2C%5Cn%20%7D%5Cn%20ctrl%20%3A%3D%20gomock.NewController(t)%5Cn%20defer%20ctrl.Finish()%5Cn%5Cn%20%2F%2F%201.%20%E7%94%9F%E6%88%90%E7%AC%A6%E5%90%88%20redis.Conn%20%E6%8E%A5%E5%8F%A3%E7%9A%84%20mockConn%5Cn%20mockConn%20%3A%3D%20NewMockConn(ctrl)%5Cn%5Cn%20%2F%2F%202.%20%E7%BB%99%E6%8E%A5%E5%8F%A3%E6%89%93%E6%A1%A9%E5%BA%8F%E5%88%97%5Cn%20gomock.InOrder(%5Cn%20%20mockConn.EXPECT().Do(%26%2334%3BGET%26%2334%3B%2C%20gomock.Any()).Return(%26%2334%3B%26%2334%3B%2C%20errors.New(%26%2334%3Bredis.Do%20err%26%2334%3B))%2C%5Cn%20%20mockConn.EXPECT().Close().Return(nil)%2C%5Cn%20%20mockConn.EXPECT().Do(%26%2334%3BGET%26%2334%3B%2C%20gomock.Any()).Return(%26%2334%3B123%26%2334%3B%2C%20nil)%2C%5Cn%20%20mockConn.EXPECT().Close().Return(nil)%2C%5Cn%20%20mockConn.EXPECT().Do(%26%2334%3BGET%26%2334%3B%2C%20gomock.Any()).Return(%5B%5Dbyte(%60%7B%26%2334%3Busername%26%2334%3B%3A%20%26%2334%3Bsteven%26%2334%3B%2C%20%26%2334%3Bemail%26%2334%3B%3A%20%26%2334%3B1234567%40qq.com%26%2334%3B%7D%60)%2C%20nil)%2C%5Cn%20%20mockConn.EXPECT().Close().Return(nil)%2C%5Cn%20)%5Cn%5Cn%20%2F%2F%203.%20%E7%BB%99%20redis.Dail%20%E5%87%BD%E6%95%B0%E6%89%93%E6%A1%A9%5Cn%20outputs%20%3A%3D%20%5B%5Dgomonkey.OutputCell%7B%5Cn%20%20%7B%5Cn%20%20%20Values%3A%20gomonkey.Params%7BmockConn%2C%20nil%7D%2C%5Cn%20%20%20Times%3A%20%203%2C%20%2F%2F%203%20%E4%B8%AA%E7%94%A8%E4%BE%8B%5Cn%20%20%7D%2C%5Cn%20%7D%5Cn%20patches%20%3A%3D%20gomonkey.ApplyFuncSeq(redis.Dial%2C%20outputs)%5Cn%20%2F%2F%20%E6%89%A7%E8%A1%8C%E5%AE%8C%E6%AF%95%E4%B9%8B%E5%90%8E%E9%87%8A%E6%94%BE%E6%A1%A9%E5%BA%8F%E5%88%97%5Cn%20defer%20patches.Reset()%5Cn%5Cn%20%2F%2F%204.%20%E6%96%AD%E8%A8%80%5Cn%20for%20_%2C%20tt%20%3A%3D%20range%20tests%20%7B%5Cn%20%20actual%2C%20err%20%3A%3D%20getPersonDetailRedis(tt.name)%5Cn%20%20%2F%2F%20%E6%B3%A8%E6%84%8F%EF%BC%8Cequal%20%E5%87%BD%E6%95%B0%E8%83%BD%E5%A4%9F%E5%AF%B9%E7%BB%93%E6%9E%84%E4%BD%93%E8%BF%9B%E8%A1%8C%20deap%20diff%5Cn%20%20assert.Equal(t%2C%20tt.want%2C%20actual)%5Cn%20%20assert.Equal(t%2C%20tt.wantErr%2C%20err%20!%3D%20nil)%5Cn%20%7D%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2260%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%BB%8E%E4%B8%8A%E9%9D%A2%E5%8F%AF%E4%BB%A5%E7%9C%8B%E5%88%B0%EF%BC%8C%E7%BB%99%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EgetPersonDetailRedis%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E5%81%9A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%BB%E8%A6%81%E5%81%9A%E4%BA%86%E5%9B%9B%E4%BB%B6%E4%BA%8B%E6%83%85%EF%BC%9A%3C%2Fp%3E%3Cul%3E%3Cli%20data-track%3D%5C%2261%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%94%9F%E6%88%90%E7%AC%A6%E5%90%88%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Eredis.Conn%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%8E%A5%E5%8F%A3%E7%9A%84%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EmockConn%3C%2Fspan%3E%3C%2Fspan%3E%3C%2Fli%3E%3Cli%20data-track%3D%5C%2262%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%BB%99%E6%8E%A5%E5%8F%A3%E6%89%93%E6%A1%A9%E5%BA%8F%E5%88%97%3C%2Fspan%3E%3C%2Fli%3E%3Cli%20data-track%3D%5C%2263%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%BB%99%E5%87%BD%E6%95%B0%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Eredis.Dial%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%89%93%E6%A1%A9%3C%2Fli%3E%3Cli%20data-track%3D%5C%2264%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%96%AD%E8%A8%80%3C%2Fspan%3E%3C%2Fli%3E%3C%2Ful%3E%3Cp%20data-track%3D%5C%2265%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%BF%99%E9%87%8C%E9%9D%A2%E5%90%8C%E6%97%B6%E4%BD%BF%E7%94%A8%E4%BA%86%20gomock%E3%80%81gomonkey%20%E5%92%8C%20testify%20%E4%B8%89%E4%B8%AA%E5%8C%85%E4%BD%9C%E4%B8%BA%E5%8E%8B%E6%B5%8B%E5%B7%A5%E5%85%B7%EF%BC%8C%E6%97%A5%E5%B8%B8%E4%BD%BF%E7%94%A8%E4%B8%AD%EF%BC%8C%E7%94%B1%E4%BA%8E%E5%A4%8D%E6%9D%82%E7%9A%84%E8%B0%83%E7%94%A8%E9%80%BB%E8%BE%91%E5%B8%A6%E6%9D%A5%E7%B9%81%E6%9D%82%E7%9A%84%E5%8D%95%E6%B5%8B%EF%BC%8C%E4%B9%9F%E6%97%A0%E5%A4%96%E4%B9%8E%E4%BD%BF%E7%94%A8%E8%BF%99%E4%B8%89%E4%B8%AA%E5%8C%85%E5%8D%8F%E5%90%8C%E5%AE%8C%E6%88%90%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2266%5C%22%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233D89FF%3B%20--tt-darkmode-color%3A%20%233D89FF%3B%5C%22%3E%E6%9F%A5%E7%9C%8B%E5%8D%95%E6%B5%8B%E6%8A%A5%E5%91%8A%3C%2Fspan%3E%3C%2Fstrong%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2267%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%BC%96%E5%86%99%E5%AE%8C%E6%AF%95%E4%B9%8B%E5%90%8E%EF%BC%8C%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E8%B0%83%E7%94%A8%E7%9B%B8%E5%85%B3%E7%9A%84%E6%8C%87%E4%BB%A4%E6%9D%A5%E6%9F%A5%E7%9C%8B%E8%A6%86%E7%9B%96%E8%8C%83%E5%9B%B4%EF%BC%8C%E5%B8%AE%E5%8A%A9%E6%88%91%E4%BB%AC%E6%9F%A5%E7%9C%8B%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E6%98%AF%E5%90%A6%E5%B7%B2%E7%BB%8F%E5%AE%8C%E5%85%A8%E8%A6%86%E7%9B%96%E9%80%BB%E8%BE%91%E4%BB%A3%E7%A0%81%EF%BC%8C%E4%BB%A5%E4%BE%BF%E6%88%91%E4%BB%AC%E5%8F%8A%E6%97%B6%E8%B0%83%E6%95%B4%E5%8D%95%E6%B5%8B%E9%80%BB%E8%BE%91%E5%92%8C%E7%94%A8%E4%BE%8B%E3%80%82%E6%9C%AC%E6%96%87%E4%B8%AD%E5%AE%8C%E6%95%B4%E7%9A%84%E5%8D%95%E6%B5%8B%E4%BB%A3%E7%A0%81%E5%8F%82%E8%80%83%EF%BC%9Aget_person_detail_test.go%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2268%5C%22%3E%3Cstrong%3E%E4%BD%BF%E7%94%A8%20go%20test%20%E6%8C%87%E4%BB%A4%3C%2Fstrong%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2269%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E9%BB%98%E8%AE%A4%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E6%88%91%E4%BB%AC%E5%9C%A8%E5%BD%93%E5%89%8D%E4%BB%A3%E7%A0%81%E7%9B%AE%E5%BD%95%E4%B8%8B%E6%89%A7%E8%A1%8C%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ego%20test%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%8C%87%E4%BB%A4%EF%BC%8C%E4%BC%9A%E8%87%AA%E5%8A%A8%E7%9A%84%E6%89%A7%E8%A1%8C%E5%BD%93%E5%89%8D%E7%9B%AE%E5%BD%95%E4%B8%8B%E9%9D%A2%E5%B8%A6%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E_test.go%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%90%8E%E7%BC%80%E7%9A%84%E6%96%87%E4%BB%B6%E8%BF%9B%E8%A1%8C%E6%B5%8B%E8%AF%95%E3%80%82%E5%A6%82%E8%8B%A5%E6%83%B3%E5%B1%95%E7%A4%BA%E5%85%B7%E4%BD%93%E7%9A%84%E6%B5%8B%E8%AF%95%E5%87%BD%E6%95%B0%E4%BB%A5%E5%8F%8A%E8%A6%86%E7%9B%96%E7%8E%87%EF%BC%8C%E5%8F%AF%E4%BB%A5%E6%B7%BB%E5%8A%A0%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E-v%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%92%8C%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E-cover%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%8F%82%E6%95%B0%EF%BC%8C%E5%A6%82%E4%B8%8B%E6%89%80%E7%A4%BA%EF%BC%9A%3C%2Fp%3E%3Cpre%3E%3Ccode%3E%E2%98%81%EF%B8%8F%20%20go_unit_test%20%5Bmaster%5D%20%20%20go%20test%20-v%20-cover%5Cn%3D%3D%3D%20RUN%20%20%20TestGetPersonDetail%5Cn---%20PASS%3A%20TestGetPersonDetail%20(0.00s)%5Cn%3D%3D%3D%20RUN%20%20%20Test_checkEmail%5Cn---%20PASS%3A%20Test_checkEmail%20(0.00s)%5Cn%3D%3D%3D%20RUN%20%20%20Test_checkUsername%5Cn---%20PASS%3A%20Test_checkUsername%20(0.00s)%5Cn%3D%3D%3D%20RUN%20%20%20Test_getPersonDetailRedis%5Cn---%20PASS%3A%20Test_getPersonDetailRedis%20(0.00s)%5CnPASS%5Cncoverage%3A%2060.8%25%20of%20statements%5Cnok%20%20%20%20%20%20unit%20%20%20%200.131s%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2271%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%A6%82%E6%9E%9C%E6%83%B3%E6%8C%87%E5%AE%9A%E6%B5%8B%E8%AF%95%E6%9F%90%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%9C%A8%E6%8C%87%E4%BB%A4%E5%90%8E%E9%9D%A2%E6%B7%BB%E5%8A%A0%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E-run%20%24%7Btest%E6%96%87%E4%BB%B6%E5%86%85%E5%87%BD%E6%95%B0%E5%90%8D%7D%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%9D%A5%E6%8C%87%E5%AE%9A%E6%89%A7%E8%A1%8C%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3E%E2%98%81%EF%B8%8F%20%20go_unit_test%20%5Bmaster%5D%20%20%20go%20test%20-cover%20-v%20%20-run%20Test_getPersonDetailRedis%5Cn%3D%3D%3D%20RUN%20%20%20Test_getPersonDetailRedis%5Cn---%20PASS%3A%20Test_getPersonDetailRedis%20(0.00s)%5CnPASS%5Cncoverage%3A%2041.9%25%20of%20statements%5Cnok%20%20%20%20%20%20unit%20%20%20%200.369s%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2273%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9C%A8%E6%89%A7%E8%A1%8C%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ego%20test%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%91%BD%E4%BB%A4%E6%97%B6%EF%BC%8C%E9%9C%80%E8%A6%81%E5%8A%A0%E4%B8%8A%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E-gcflags%3Dall%3D-l%3C%2Fspan%3E%3C%2Fspan%3E%20%E9%98%B2%E6%AD%A2%E7%BC%96%E8%AF%91%E5%99%A8%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E5%AF%BC%E8%87%B4%E5%8D%95%E6%B5%8B%E5%87%BA%E7%8E%B0%E9%97%AE%E9%A2%98%EF%BC%8C%E8%BF%99%E8%B7%9F%E6%89%93%E6%A1%A9%E4%BB%A3%E7%A0%81%E5%AD%98%E5%9C%A8%E5%AF%86%E5%88%87%E7%9A%84%E5%85%B3%E7%B3%BB%EF%BC%8C%E5%90%8E%E9%9D%A2%E6%88%91%E4%BB%AC%E4%BC%9A%E8%AF%A6%E7%BB%86%E7%9A%84%E4%BB%8B%E7%BB%8D%E8%BF%99%E4%B8%80%E7%82%B9%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2274%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9B%A0%E6%AD%A4%EF%BC%8C%E4%B8%80%E4%B8%AA%E5%AE%8C%E6%95%B4%E7%9A%84%E5%8D%95%E6%B5%8B%E6%8C%87%E4%BB%A4%E5%8F%AF%E4%BB%A5%E6%98%AF%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ego%20test%20-v%20-cover%20-gcflags%3Dall%3D-l%20-coverprofile%3Dcoverage.out%3C%2Fspan%3E%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2275%5C%22%3E%3Cstrong%3E%E7%94%9F%E6%88%90%E8%A6%86%E7%9B%96%E6%8A%A5%E5%91%8A%3C%2Fstrong%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2276%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%9C%80%E5%90%8E%EF%BC%8C%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E6%89%A7%E8%A1%8C%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ego%20tool%20cover%20-html%3Dcoverage.out%3C%2Fspan%3E%3C%2Fspan%3E%20%EF%BC%8C%E6%9F%A5%E7%9C%8B%E4%BB%A3%E7%A0%81%E7%9A%84%E8%A6%86%E7%9B%96%E6%83%85%E5%86%B5%EF%BC%8C%E4%BD%BF%E7%94%A8%E5%89%8D%E8%AF%B7%E5%85%88%E5%AE%89%E8%A3%85%E5%A5%BD%20go%20tool%20%E5%B7%A5%E5%85%B7%E3%80%82%3C%2Fp%3E%3Cdiv%20class%3D%5C%22pgc-img%5C%22%3E%3Cimg%20src%3D%5C%22https%3A%2F%2Fp3-sign.toutiaoimg.com%2Ftos-cn-i-qvj2lq49k0%2Fe108da3ebb3741d7af7665d5a59ff21c~tplv-tt-origin-web%3Agif.jpeg%3F_iz%3D58558%26from%3Darticle.pc_detail%26lk3s%3D953192f4%26x-expires%3D1734609857%26x-signature%3DVvb2b50Q84K4UtpZubecV0HS6HQ%253D%5C%22%20img_width%3D%5C%22876%5C%22%20img_height%3D%5C%22979%5C%22%20image_type%3D%5C%221%5C%22%20mime_type%3D%5C%22image%2Fjpeg%5C%22%20web_uri%3D%5C%22tos-cn-i-qvj2lq49k0%2Fe108da3ebb3741d7af7665d5a59ff21c%5C%22%3E%3Cp%20class%3D%5C%22pgc-img-caption%5C%22%3E%3C%2Fp%3E%3C%2Fdiv%3E%3Cp%20data-track%3D%5C%2278%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%8F%AF%E4%BB%A5%E7%9C%8B%E5%88%B0%E5%BE%85%E6%B5%8B%E7%9A%84%E4%BB%A3%E7%A0%81%E8%A6%86%E7%9B%96%E7%8E%87%E8%BE%BE%E5%88%B0%20100%25%20%E4%BA%86%EF%BC%8C%E5%AE%8C%E6%95%B4%E7%9A%84%E4%BB%A3%E7%A0%81%E4%BB%93%E5%BA%93%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%EF%BC%9Ahttps%3A%2F%2Fgithub.com%2Fxunan007%2Fgo_unit_test%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2279%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%85%B3%E4%BA%8E%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ego%20test%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%9B%B4%E5%A4%9A%E7%9A%84%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%EF%BC%9A%3C%2Fp%3E%3Cp%20data-track%3D%5C%2280%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3Ehttps%3A%2F%2Fgolang.org%2Fpkg%2Fcmd%2Fgo%2Finternal%2Ftest%2F%3C%2Fspan%3E%3C%2Fp%3E%3Ch1%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2281%5C%22%3E%E6%80%9D%E8%80%83%3C%2Fh1%3E%3Cp%20data-track%3D%5C%2282%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%B8%8A%E9%9D%A2%E6%88%91%E4%BB%AC%E5%B7%B2%E7%BB%8F%E8%AF%A6%E7%BB%86%E7%9A%84%E4%BB%8B%E7%BB%8D%E4%BA%86%E5%A6%82%E4%BD%95%E5%AF%B9%20go%20%E4%BB%A3%E7%A0%81%E8%BF%9B%E8%A1%8C%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E3%80%82%E4%B8%8B%E9%9D%A2%E6%8E%A2%E8%AE%A8%E4%B8%A4%E4%B8%AA%E9%97%AE%E9%A2%98%EF%BC%8C%E5%B8%AE%E5%8A%A9%E6%88%91%E4%BB%AC%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3%20go%20%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E7%9A%84%E8%BF%87%E7%A8%8B%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%2283%5C%22%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233D89FF%3B%20--tt-darkmode-color%3A%20%233D89FF%3B%5C%22%3EQ1%EF%BC%9A%E6%A1%A9%E4%BB%A3%E7%A0%81%E5%9C%A8%E5%8D%95%E6%B5%8B%E4%B8%AD%E6%98%AF%E5%A6%82%E4%BD%95%E6%89%A7%E8%A1%8C%E7%9A%84%3C%2Fspan%3E%3C%2Fstrong%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2284%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9C%A8%E4%B8%8A%E9%9D%A2%E7%9A%84%E6%A1%88%E4%BE%8B%E4%B8%AD%EF%BC%8C%E9%92%88%E5%AF%B9%20interface%20%E6%88%91%E4%BB%AC%E9%80%9A%E8%BF%87%20gomock%20%E6%9D%A5%E5%B8%AE%E6%88%91%E4%BB%AC%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90%E7%AC%A6%E5%90%88%E6%8E%A5%E5%8F%A3%E7%9A%84%E7%B1%BB%E5%90%8E%EF%BC%8C%E5%8F%AA%E9%9C%80%E8%A6%81%E9%80%9A%E8%BF%87%20gomock%20%E7%BA%A6%E5%AE%9A%E7%9A%84%20API%20%E5%B0%B1%E8%83%BD%E5%A4%9F%E5%AF%B9%20interface%20%E4%B8%AD%E7%9A%84%E5%87%BD%E6%95%B0%E6%8C%89%E6%9C%9F%E6%9C%9B%E5%92%8C%E9%9C%80%E8%A6%81%E6%9D%A5%E6%A8%A1%E6%8B%9F%EF%BC%8C%E8%BF%99%E4%B8%AA%E5%BE%88%E5%A5%BD%E7%90%86%E8%A7%A3%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2285%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%AF%B9%E4%BA%8E%E5%87%BD%E6%95%B0%E4%BB%A5%E5%8F%8A%E6%96%B9%E6%B3%95%E7%9A%84%20mock%EF%BC%8C%E7%94%B1%E4%BA%8E%E6%9C%AC%E8%BA%AB%E4%BB%A3%E7%A0%81%E9%80%BB%E8%BE%91%E5%B7%B2%E7%BB%8F%E5%A3%B0%E6%98%8E%E5%A5%BD%EF%BC%88go%20%E6%98%AF%E9%9D%99%E6%80%81%E5%BC%BA%E7%B1%BB%E5%9E%8B%E8%AF%AD%E8%A8%80%EF%BC%89%EF%BC%8C%E6%88%91%E4%BB%AC%E5%BE%88%E9%9A%BE%E9%80%9A%E8%BF%87%E7%BC%96%E7%A0%81%E7%9A%84%E6%96%B9%E5%BC%8F%E5%B0%86%E5%85%B6%20mock%20%E6%8E%89%EF%BC%8C%E8%BF%99%E5%AF%B9%E6%88%91%E4%BB%AC%E5%81%9A%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E6%8F%90%E4%BE%9B%E4%BA%86%E5%BE%88%E5%A4%A7%E7%9A%84%E6%8C%91%E6%88%98%E3%80%82%E5%AE%9E%E9%99%85%E4%B8%8A%20gomonkey%20%E6%8F%90%E4%BE%9B%E4%BA%86%E8%AE%A9%E6%88%91%E4%BB%AC%E5%9C%A8%E8%BF%90%E8%A1%8C%E6%97%B6%E6%9B%BF%E6%8D%A2%E5%8E%9F%E5%87%BD%E6%95%B0%2F%E6%96%B9%E6%B3%95%E7%9A%84%E8%83%BD%E5%8A%9B%E3%80%82%E8%99%BD%E7%84%B6%E8%AF%B4%E6%88%91%E4%BB%AC%E5%9C%A8%E8%AF%AD%E8%A8%80%E5%B1%82%E9%9D%A2%E5%BE%88%E9%9A%BE%E5%8E%BB%E6%9B%BF%E6%8D%A2%E8%BF%90%E8%A1%8C%E4%B8%AD%E7%9A%84%E5%87%BD%E6%95%B0%E4%BD%93%EF%BC%8C%E4%BD%86%E6%98%AF%E6%9C%AC%E8%BA%AB%E4%BB%A3%E7%A0%81%E6%9C%80%E7%BB%88%E9%83%BD%E4%BC%9A%E8%BD%AC%E6%8D%A2%E6%88%90%E6%9C%BA%E5%99%A8%E5%8F%AF%E4%BB%A5%E7%90%86%E8%A7%A3%E7%9A%84%E6%B1%87%E7%BC%96%E6%8C%87%E4%BB%A4%EF%BC%8C%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E5%88%9B%E5%BB%BA%E6%8C%87%E4%BB%A4%E6%9D%A5%E6%94%B9%E5%86%99%E5%87%BD%E6%95%B0%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2286%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9C%A8%20gomonkey%20%E6%89%93%E6%A1%A9%E7%9A%84%E8%BF%87%E7%A8%8B%E4%B8%AD%EF%BC%8C%E5%85%B6%E6%A0%B8%E5%BF%83%E5%87%BD%E6%95%B0%E5%85%B6%E5%AE%9E%E6%98%AF%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EApplyCore%3C%2Fspan%3E%3C%2Fspan%3E%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3Efunc%20(this%20*Patches)%20ApplyCore(target%2C%20double%20reflect.Value)%20*Patches%20%7B%5Cn%20this.check(target%2C%20double)%5Cn%20if%20_%2C%20ok%20%3A%3D%20this.originals%5Btarget%5D%3B%20ok%20%7B%5Cn%20%20panic(%26%2334%3Bpatch%20has%20been%20existed%26%2334%3B)%5Cn%20%7D%5Cn%5Cn%20this.valueHolders%5Bdouble%5D%20%3D%20double%5Cn%20original%20%3A%3D%20replace(*(*uintptr)(getPointer(target))%2C%20uintptr(getPointer(double)))%5Cn%20this.originals%5Btarget%5D%20%3D%20original%5Cn%20return%20this%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2288%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%B8%8D%E7%AE%A1%E6%98%AF%E5%AF%B9%E5%87%BD%E6%95%B0%E6%89%93%E6%A1%A9%E8%BF%98%E6%98%AF%E5%AF%B9%E6%96%B9%E6%B3%95%E6%89%93%E6%A1%A9%EF%BC%8C%E5%AE%9E%E9%99%85%E4%B8%8A%E6%9C%80%E5%90%8E%E9%83%BD%E4%BC%9A%E8%B0%83%E7%94%A8%E8%BF%99%E4%B8%AA%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EApplyCore%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2289%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9C%A8%E7%AC%AC%208%20%E8%A1%8C%E7%9A%84%E4%BD%8D%E7%BD%AE%EF%BC%8C%E8%8E%B7%E5%8F%96%E5%88%B0%E4%BC%A0%E5%85%A5%E7%9A%84%E5%8E%9F%E5%A7%8B%E5%87%BD%E6%95%B0%E5%92%8C%E6%9B%BF%E6%8D%A2%E5%87%BD%E6%95%B0%E5%81%9A%E4%BA%86%E4%B8%80%E4%B8%AA%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ereplace%3C%2Fspan%3E%3C%2Fspan%3E%20%E7%9A%84%E6%93%8D%E4%BD%9C%EF%BC%8C%E8%BF%99%E9%87%8C%E5%B0%B1%E6%98%AF%E6%9B%BF%E6%8D%A2%E7%9A%84%E9%80%BB%E8%BE%91%E6%89%80%E5%9C%A8%E4%BA%86%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3Efunc%20replace(target%2C%20double%20uintptr)%20%5B%5Dbyte%20%7B%5Cn%20code%20%3A%3D%20buildJmpDirective(double)%5Cn%20bytes%20%3A%3D%20entryAddress(target%2C%20len(code))%5Cn%20original%20%3A%3D%20make(%5B%5Dbyte%2C%20len(bytes))%5Cn%20copy(original%2C%20bytes)%5Cn%20modifyBinary(target%2C%20code)%5Cn%20return%20original%5Cn%7D%5Cn%5Cn%2F%2F%20%E5%85%B3%E9%94%AE%E5%87%BD%E6%95%B0%EF%BC%9A%E6%9E%84%E5%BB%BA%E8%B7%B3%E8%BD%AC%E6%8C%87%E4%BB%A4%5Cnfunc%20buildJmpDirective(double%20uintptr)%20%5B%5Dbyte%20%7B%5Cn%20%20%20%20d0%20%3A%3D%20byte(double)%5Cn%20%20%20%20d1%20%3A%3D%20byte(double%20%26gt%3B%26gt%3B%208)%5Cn%20%20%20%20d2%20%3A%3D%20byte(double%20%26gt%3B%26gt%3B%2016)%5Cn%20%20%20%20d3%20%3A%3D%20byte(double%20%26gt%3B%26gt%3B%2024)%5Cn%20%20%20%20d4%20%3A%3D%20byte(double%20%26gt%3B%26gt%3B%2032)%5Cn%20%20%20%20d5%20%3A%3D%20byte(double%20%26gt%3B%26gt%3B%2040)%5Cn%20%20%20%20d6%20%3A%3D%20byte(double%20%26gt%3B%26gt%3B%2048)%5Cn%20%20%20%20d7%20%3A%3D%20byte(double%20%26gt%3B%26gt%3B%2056)%5Cn%5Cn%20%20%20%20return%20%5B%5Dbyte%7B%5Cn%20%20%20%20%20%20%20%200x48%2C%200xBA%2C%20d0%2C%20d1%2C%20d2%2C%20d3%2C%20d4%2C%20d5%2C%20d6%2C%20d7%2C%20%2F%2F%20MOV%20rdx%2C%20double%5Cn%20%20%20%20%20%20%20%200xFF%2C%200x22%2C%20%20%20%20%20%2F%2F%20JMP%20%5Brdx%5D%5Cn%20%20%20%20%7D%5Cn%7D%5Cn%5Cn%2F%2F%20%E5%85%B3%E9%94%AE%E5%87%BD%E6%95%B0%EF%BC%9A%E9%87%8D%E5%86%99%E7%9B%AE%E6%A0%87%E5%87%BD%E6%95%B0%5Cnfunc%20modifyBinary(target%20uintptr%2C%20bytes%20%5B%5Dbyte)%20%7B%5Cn%20%20%20%20function%20%3A%3D%20entryAddress(target%2C%20len(bytes))%5Cn%5Cn%20%20%20%20page%20%3A%3D%20entryAddress(pageStart(target)%2C%20syscall.Getpagesize())%5Cn%20%20%20%20err%20%3A%3D%20syscall.Mprotect(page%2C%20syscall.PROT_READ%7Csyscall.PROT_WRITE%7Csyscall.PROT_EXEC)%5Cn%20%20%20%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20%20%20%20%20%20%20panic(err)%5Cn%20%20%20%20%7D%5Cn%20%20%20%20copy(function%2C%20bytes)%5Cn%5Cn%20%20%20%20err%20%3D%20syscall.Mprotect(page%2C%20syscall.PROT_READ%7Csyscall.PROT_EXEC)%5Cn%20%20%20%20if%20err%20!%3D%20nil%20%7B%5Cn%20%20%20%20%20%20%20%20panic(err)%5Cn%20%20%20%20%7D%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2291%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%BB%8E%E4%B8%8A%E9%9D%A2%E7%9A%84%E4%BB%A3%E7%A0%81%E5%8F%AF%E4%BB%A5%E7%9C%8B%E5%87%BA%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EbuildJmpDirective%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%9E%84%E5%BB%BA%E4%BA%86%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%E8%B7%B3%E8%BD%AC%E7%9A%84%E6%8C%87%E4%BB%A4%EF%BC%8C%E6%8A%8A%E7%9B%AE%E6%A0%87%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88%E7%A7%BB%E5%8A%A8%E5%88%B0%E5%AF%84%E5%AD%98%E5%99%A8%20rdx%20%E4%B8%AD%EF%BC%8C%E7%84%B6%E5%90%8E%E8%B7%B3%E8%BD%AC%E5%88%B0%E5%AF%84%E5%AD%98%E5%99%A8%20rdx%20%E4%B8%AD%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88%E6%8C%87%E5%90%91%E7%9A%84%E5%9C%B0%E5%9D%80%E3%80%82%E4%B9%8B%E5%90%8E%E9%80%9A%E8%BF%87%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EmodifyBinary%3C%2Fspan%3E%3C%2Fspan%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%20%3C%2Fspan%3E%E5%87%BD%E6%95%B0%EF%BC%8C%E5%85%88%E9%80%9A%E8%BF%87%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EentryAddress%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%96%B9%E6%B3%95%E8%8E%B7%E5%8F%96%E5%88%B0%E5%8E%9F%E5%87%BD%E6%95%B0%E6%89%80%E5%9C%A8%E7%9A%84%E5%86%85%E5%AD%98%E5%9C%B0%E5%9D%80%EF%BC%8C%E4%B9%8B%E5%90%8E%E9%80%9A%E8%BF%87%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Esyscall.Mprotect%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%96%B9%E6%B3%95%E6%89%93%E5%BC%80%E5%86%85%E5%AD%98%E4%BF%9D%E6%8A%A4%EF%BC%8C%E5%B0%86%E5%87%BD%E6%95%B0%E8%B7%B3%E8%BD%AC%E6%8C%87%E4%BB%A4%E4%BB%A5%20bytes%20%E6%95%B0%E7%BB%84%E7%9A%84%E5%BD%A2%E5%BC%8F%E8%B0%83%E7%94%A8%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ecopy%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%96%B9%E6%B3%95%E5%86%99%E5%85%A5%E5%88%B0%E5%8E%9F%E5%87%BD%E6%95%B0%E6%89%80%E5%9C%A8%E5%86%85%E5%AD%98%E4%B9%8B%E4%B8%AD%EF%BC%8C%E6%9C%80%E7%BB%88%E8%BE%BE%E5%88%B0%E6%9B%BF%E6%8D%A2%E7%9A%84%E7%9B%AE%E7%9A%84%E3%80%82%E6%AD%A4%E5%A4%96%EF%BC%8C%E8%BF%99%E9%87%8C%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ereplace%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%96%B9%E6%B3%95%E8%BF%98%E4%BF%9D%E7%95%99%E4%BA%86%E5%8E%9F%E5%87%BD%E6%95%B0%E7%9A%84%E5%89%AF%E6%9C%AC%EF%BC%8C%E6%96%B9%E4%BE%BF%E5%90%8E%E7%BB%AD%E5%87%BD%E6%95%B0%20mock%20%E7%9A%84%E6%81%A2%E5%A4%8D%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2292%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%B8%BA%E4%BB%80%E4%B9%88%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EbuildJmpDirective%3C%2Fspan%3E%3C%2Fspan%3E%20%E8%A6%81%E6%9E%84%E5%BB%BA%E8%BF%99%E6%A0%B7%E7%9A%84%E8%B7%B3%E8%BD%AC%E6%8C%87%E4%BB%A4%E5%91%A2%EF%BC%9F%E8%BF%99%E9%87%8C%E5%8F%AA%E8%AF%B4%E7%BB%93%E8%AE%BA%EF%BC%8C%E5%85%B7%E4%BD%93%E7%9A%84%E6%8E%A8%E5%AF%BC%E8%BF%87%E7%A8%8B%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%EF%BC%9Ahttps%3A%2F%2Fbou.ke%2Fblog%2Fmonkey-patching-in-go%3C%2Fp%3E%3Cpre%3E%3Ccode%3Epackage%20main%5Cnfunc%20a()%20int%20%7B%20return%201%20%7D%5Cnfunc%20main()%20%7B%5Cn%20%20f%20%3A%3D%20a%5Cn%20%20f()%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%2294%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%B8%8A%E9%9D%A2%E8%BF%99%E6%AE%B5%E4%BB%A3%E7%A0%81%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ea%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%98%AF%E4%B8%80%E4%B8%AA%E6%8C%87%E5%90%91%E5%87%BD%E6%95%B0%E5%AE%9E%E4%BD%93%E7%9A%84%E6%8C%87%E9%92%88%EF%BC%8C%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ef%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%98%AF%E6%8C%87%E5%90%91%E5%87%BD%E6%95%B0%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ea%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%8C%87%E9%92%88%E7%9A%84%E6%8C%87%E9%92%88%E3%80%82%E6%8A%8A%E4%B8%8A%E9%9D%A2%E5%87%BD%E6%95%B0%E7%9A%84%E8%B0%83%E7%94%A8%E5%8F%8D%E6%B1%87%E7%BC%96%EF%BC%8C%E8%83%BD%E5%A4%9F%E7%9C%8B%E5%88%B0%E6%93%8D%E4%BD%9C%E5%AF%84%E5%AD%98%E5%99%A8%E7%9A%84%E5%85%B7%E4%BD%93%E7%BB%86%E8%8A%82%E3%80%82%EF%BC%88%20%E5%A6%82%E6%9E%9C%E5%AF%B9%E6%B1%87%E7%BC%96%E4%B8%8D%E6%98%AF%E5%BE%88%E4%BA%86%E8%A7%A3%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%85%88%E9%98%85%E8%AF%BB%20http%3A%2F%2Fwww.ruanyifeng.com%2Fblog%2F2018%2F01%2Fassembly-language-primer.html%20%EF%BC%89%3C%2Fp%3E%3Cdiv%20class%3D%5C%22pgc-img%5C%22%3E%3Cimg%20src%3D%5C%22https%3A%2F%2Fp3-sign.toutiaoimg.com%2Ftos-cn-i-qvj2lq49k0%2F2f1220bbf1064c8a9eb83d7188697332~tplv-tt-origin-web%3Agif.jpeg%3F_iz%3D58558%26from%3Darticle.pc_detail%26lk3s%3D953192f4%26x-expires%3D1734609857%26x-signature%3D6LvsZwDUwu%252BW76ZO0A0u9onC%252BDQ%253D%5C%22%20img_width%3D%5C%22884%5C%22%20img_height%3D%5C%2286%5C%22%20image_type%3D%5C%221%5C%22%20mime_type%3D%5C%22image%2Fjpeg%5C%22%20web_uri%3D%5C%22tos-cn-i-qvj2lq49k0%2F2f1220bbf1064c8a9eb83d7188697332%5C%22%3E%3Cp%20class%3D%5C%22pgc-img-caption%5C%22%3E%3C%2Fp%3E%3C%2Fdiv%3E%3Cp%20data-track%3D%5C%2295%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%AC%AC%E4%B8%80%E8%A1%8C%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Elea%3C%2Fspan%3E%3C%2Fspan%3E%20%E4%B8%BA%20load%20effective%20address%EF%BC%8C%E8%BF%99%E9%87%8C%E6%98%AF%E5%B0%86%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%231E6BB8%3B%5C%22%3Ef%3C%2Fspan%3E%20%E5%8F%98%E9%87%8F%E8%BF%99%E4%B8%AA%E5%80%BC%E7%9B%B4%E6%8E%A5%E8%B5%8B%E7%BB%99%20rdx%20%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%8C%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ef%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%8F%98%E9%87%8F%E7%9A%84%E5%80%BC%E6%98%AF%E6%8C%87%E5%90%91%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ea%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E7%9A%84%E5%9C%B0%E5%9D%80%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2296%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%AC%AC%E4%BA%8C%E8%A1%8C%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Emov%3C%2Fspan%3E%3C%2Fspan%3E%20%E8%A1%A8%E7%A4%BA%E7%A7%BB%E5%8A%A8%EF%BC%8C%E8%BF%99%E9%87%8C%E6%98%AF%E5%8F%96%E5%88%B0%E5%86%85%E5%AD%98%E5%9C%B0%E5%9D%80%E4%B8%BA%20rdx%20%E7%9A%84%E6%95%B0%E6%8D%AE%E8%B5%8B%E5%80%BC%E7%BB%99%20rbx%EF%BC%8C%E6%AD%A4%E6%97%B6%E5%86%85%E5%AD%98%E5%9C%B0%E5%9D%80%20rbx%20%E6%8C%87%E5%90%91%E7%9A%84%E5%88%9A%E5%A5%BD%E5%B0%B1%E6%98%AF%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ea%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%2297%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%9C%80%E5%90%8E%EF%BC%8C%E8%B0%83%E7%94%A8%20rbx%20%E9%87%8C%E9%9D%A2%E7%9A%84%E5%86%85%E5%AE%B9%EF%BC%8C%E5%85%B6%E5%AE%9E%E4%B9%9F%E5%B0%B1%E6%98%AF%E6%89%A7%E8%A1%8C%E5%87%BD%E6%95%B0%E4%BD%93%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%2298%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9B%A0%E6%AD%A4%EF%BC%8C%E6%88%91%E4%BB%AC%E6%83%B3%E6%94%B9%E5%86%99%E5%87%BD%E6%95%B0%EF%BC%8C%E5%8F%AA%E8%A6%81%E6%83%B3%E5%8A%9E%E6%B3%95%E6%8A%8A%E9%9C%80%E8%A6%81%E8%B7%B3%E8%BD%AC%E7%9A%84%E5%87%BD%E6%95%B0%E7%9A%84%E5%9C%B0%E5%9D%80%E5%8A%A0%E8%BD%BD%E5%88%B0%20rdx%20%E5%AF%84%E5%AD%98%E5%99%A8%E4%B8%AD%EF%BC%8C%E4%B9%8B%E5%90%8E%E4%BD%BF%E7%94%A8%E6%8C%87%E4%BB%A4%E8%B7%B3%E8%BD%AC%E6%89%A7%E8%A1%8C%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cpre%3E%3Ccode%3EMOV%20rdx%2C%20double%5CnJMP%20%5Brdx%5D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%22100%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%9C%80%E7%BB%88%EF%BC%8C%E6%8A%8A%E6%B1%87%E7%BC%96%E6%8C%87%E4%BB%A4%E7%BF%BB%E8%AF%91%E6%88%90%20go%20%E8%83%BD%E5%A4%9F%E8%AF%86%E5%88%AB%E7%9A%84%E7%89%88%E6%9C%AC%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%22101%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%BF%99%E5%85%B6%E5%AE%9E%E4%B9%9F%E6%98%AF%E6%B1%87%E7%BC%96%E9%87%8C%E9%9D%A2%E5%BE%88%E5%B8%B8%E8%A7%81%E7%9A%84%E7%83%AD%E8%A1%A5%E4%B8%81%EF%BC%8C%E5%A4%9A%E7%94%A8%E4%BA%8E%E8%BF%9B%E7%A8%8B%E4%B8%AD%E5%87%BD%E6%95%B0%E7%9A%84%E6%9B%BF%E6%8D%A2%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20class%3D%5C%22pgc-h-arrow-right%5C%22%20data-track%3D%5C%22102%5C%22%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233D89FF%3B%20--tt-darkmode-color%3A%20%233D89FF%3B%5C%22%3EQ2%EF%BC%9A%E6%89%A7%E8%A1%8C%20-gcflags%3Dall%3D-l%20%E5%85%B7%E4%BD%93%E6%9C%89%E4%BB%80%E4%B9%88%E4%BD%9C%E7%94%A8%3C%2Fspan%3E%3C%2Fstrong%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%22103%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E-gcflags%3C%2Fspan%3E%3C%2Fspan%3E%20%E7%94%A8%E4%BA%8E%E5%9C%A8%20go%20%E7%BC%96%E8%AF%91%E6%9E%84%E5%BB%BA%E6%97%B6%E8%BF%9B%E8%A1%8C%E5%8F%82%E6%95%B0%E7%9A%84%E4%BC%A0%E9%80%92%EF%BC%8C%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Eall%3C%2Fspan%3E%3C%2Fspan%3E%20%E8%A1%A8%E7%A4%BA%E8%A6%86%E7%9B%96%E6%89%80%E6%9C%89%E5%9C%A8%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EGOPATH%3C%2Fspan%3E%3C%2Fspan%3E%20%E4%B8%AD%E7%9A%84%E5%8C%85%EF%BC%8C%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E-l%3C%2Fspan%3E%3C%2Fspan%3E%20%E8%A1%A8%E7%A4%BA%E7%A6%81%E6%AD%A2%E7%BC%96%E8%AF%91%E7%9A%84%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E3%80%82%E8%AF%A5%E6%8C%87%E4%BB%A4%E5%8F%AF%E4%BB%A5%E9%98%B2%E6%AD%A2%E7%BC%96%E8%AF%91%E6%97%B6%E4%BB%A3%E7%A0%81%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E4%BD%BF%E5%BE%97%20mock%20%E5%A4%B1%E8%B4%A5%EF%BC%8C%3Cstrong%3E%E6%9C%80%E7%BB%88%E5%AF%BC%E8%87%B4%E6%89%A7%E8%A1%8C%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E4%B8%8D%E9%80%9A%E8%BF%87%3C%2Fstrong%3E%E3%80%82%E4%B8%8B%E9%9D%A2%E6%88%91%E4%BB%AC%E5%85%B7%E4%BD%93%E6%9D%A5%E6%8E%A2%E8%AE%A8%E4%B8%80%E4%B8%8B%E2%80%9C%E5%86%85%E8%81%94%E2%80%9D%E4%BB%A5%E5%8F%8A%E7%BB%99%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E5%B8%A6%E6%9D%A5%E7%9A%84%E5%BD%B1%E5%93%8D%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%22104%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E9%80%9A%E4%BF%97%E6%9D%A5%E8%AE%B2%EF%BC%8C%E5%86%85%E8%81%94%E6%8C%87%E7%9A%84%E6%98%AF%E6%8A%8A%E7%AE%80%E7%9F%AD%E7%9A%84%E5%87%BD%E6%95%B0%E5%9C%A8%E8%B0%83%E7%94%A8%E5%AE%83%E7%9A%84%E5%9C%B0%E6%96%B9%E5%B1%95%E5%BC%80%E3%80%82%E7%94%B1%E4%BA%8E%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E6%9C%89%E5%9B%BA%E5%AE%9A%E7%9A%84%E5%BC%80%E9%94%80%EF%BC%88%E6%A0%88%E5%92%8C%E6%8A%A2%E5%8D%A0%E6%A3%80%E6%9F%A5%EF%BC%89%EF%BC%8C%E5%9C%A8%E7%BC%96%E8%AF%91%E8%BF%87%E7%A8%8B%E4%B8%AD%EF%BC%8C%E7%BC%96%E8%AF%91%E5%99%A8%E5%8F%AF%E4%BB%A5%E9%92%88%E5%AF%B9%E4%BB%A3%E7%A0%81%E8%BF%9B%E8%A1%8C%E5%86%85%E8%81%94%EF%BC%8C%E5%87%8F%E5%B0%91%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E5%BC%80%E9%94%80%E3%80%82%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E6%98%AF%E9%AB%98%E6%80%A7%E8%83%BD%E7%BC%96%E7%A8%8B%E7%9A%84%E4%B8%80%E7%A7%8D%E9%87%8D%E8%A6%81%E6%89%8B%E6%AE%B5%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%22105%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%9C%A8%20go%20%E4%B8%AD%EF%BC%8C%E7%BC%96%E8%AF%91%E5%99%A8%E4%B8%8D%E4%BC%9A%E5%AF%B9%E6%89%80%E6%9C%89%E7%AE%80%E5%8D%95%E5%87%BD%E6%95%B0%E8%BF%9B%E8%A1%8C%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E3%80%82go%20%E5%9C%A8%E5%86%B3%E7%AD%96%E6%98%AF%E5%90%A6%E8%A6%81%E5%AF%B9%E5%87%BD%E6%95%B0%E8%BF%9B%E8%A1%8C%E5%86%85%E8%81%94%E6%97%B6%E6%9C%89%E4%B8%80%E4%B8%AA%E6%A0%87%E5%87%86%EF%BC%9A%E5%87%BD%3C%2Fspan%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E6%95%B0%E4%BD%93%E5%86%85%E5%8C%85%E5%90%AB%EF%BC%9A%E9%97%AD%E5%8C%85%E8%B0%83%E7%94%A8%EF%BC%8Cselect%20%EF%BC%8Cfor%20%EF%BC%8Cdefer%EF%BC%8Cgo%20%E5%85%B3%E9%94%AE%E5%AD%97%E7%9A%84%E7%9A%84%E5%87%BD%E6%95%B0%E4%B8%8D%E4%BC%9A%E8%BF%9B%E8%A1%8C%E5%86%85%E8%81%94%E3%80%82%E5%B9%B6%E4%B8%94%E9%99%A4%E4%BA%86%E8%BF%99%E4%BA%9B%EF%BC%8C%E8%BF%98%E6%9C%89%E5%85%B6%E5%AE%83%E7%9A%84%E9%99%90%E5%88%B6%E3%80%82%E5%BD%93%E8%A7%A3%E6%9E%90%20AST%20%E6%97%B6%EF%BC%8CGo%20%E7%94%B3%E8%AF%B7%E4%BA%86%2080%20%E4%B8%AA%E8%8A%82%E7%82%B9%E4%BD%9C%E4%B8%BA%E5%86%85%E8%81%94%E7%9A%84%E9%A2%84%E7%AE%97%E3%80%82%E6%AF%8F%E4%B8%AA%E8%8A%82%E7%82%B9%E9%83%BD%E4%BC%9A%E6%B6%88%E8%80%97%E4%B8%80%E4%B8%AA%E9%A2%84%E7%AE%97%E3%80%82%E5%BD%93%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%E7%9A%84%E5%BC%80%E9%94%80%E8%B6%85%E8%BF%87%E4%BA%86%E8%BF%99%E4%B8%AA%E9%A2%84%E7%AE%97%EF%BC%8C%E5%B0%B1%E6%97%A0%E6%B3%95%E5%86%85%E8%81%94%E3%80%82%3C%2Fspan%3E%3C%2Fstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%EF%BC%88%20%E5%8F%82%E8%80%83%E8%87%AA%EF%BC%9Ahttps%3A%2F%2Fjuejin.cn%2Fpost%2F6924888439577903117%20%EF%BC%89%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%22106%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%B8%8B%E9%9D%A2%E6%88%91%E4%BB%AC%E9%80%9A%E8%BF%87%E4%B8%80%E6%AE%B5%E7%AE%80%E7%9F%AD%E7%9A%84%E4%BB%A3%E7%A0%81%E6%9D%A5%E7%90%86%E8%A7%A3%20go%20%E7%BC%96%E8%AF%91%E8%BF%87%E7%A8%8B%E7%9A%84%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E8%BF%87%E7%A8%8B%E3%80%82%E6%88%91%E4%BB%AC%E4%BB%8E%20gomonkey%20%E5%85%B3%E4%BA%8E%E5%86%85%E8%81%94%E7%9A%84%20issue%20%E6%91%98%E5%8F%96%E4%BA%86%E4%B8%80%E6%AE%B5%E4%BB%A3%E7%A0%81%EF%BC%9A%3C%2Fspan%3E%3C%2Fp%3E%3Cpre%3E%3Ccode%3Epackage%20main%5Cnimport%20%26%2334%3Bfmt%26%2334%3B%5Cnfunc%20G2()%20string%20%7B%20%20return%20%26%2334%3BG2%26%2334%3B%20%7D%5Cnfunc%20G()%20string%20%7B%20%20return%20G2()%20%7D%5Cnfunc%20main()%20%7B%5Cn%20%20g%20%3A%3D%20G()%5Cn%20%20fmt.Println(g)%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%22108%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%B8%8A%E9%9D%A2%E8%BF%99%E6%AE%B5%E4%BB%A3%E7%A0%81%E5%BE%88%E7%AE%80%E5%8D%95%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Emain%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E4%B8%AD%E8%B0%83%E7%94%A8%E4%BA%86%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E6%8B%BF%E5%88%B0%E8%BF%94%E5%9B%9E%E5%80%BC%E8%B5%8B%E5%80%BC%E5%8F%98%E9%87%8F%E7%BB%99%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Eg%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%90%8E%E6%89%93%E5%8D%B0%E7%BB%93%E6%9E%9C%E3%80%82%E5%85%B6%E4%B8%AD%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E4%BA%86%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG2%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%EF%BC%8C%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG2%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E8%BF%94%E5%9B%9E%E4%BA%86%E5%AD%97%E7%AC%A6%E4%B8%B2%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3E%26%2334%3BG2%26%2334%3B%3C%2Fspan%3E%3C%2Fspan%3E%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%22109%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E7%84%B6%E8%80%8C%EF%BC%8C%E7%BB%8F%E8%BF%87%E7%BC%96%E8%AF%91%E5%99%A8%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E5%90%8E%E7%9A%84%E4%BB%A3%E7%A0%81%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E5%AE%9E%E9%99%85%E8%A2%AB%E5%B1%95%E5%BC%80%E4%BA%86%EF%BC%8C%E6%9C%80%E7%BB%88%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Emain%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E8%A2%AB%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E6%88%90%EF%BC%9A%3C%2Fp%3E%3Cpre%3E%3Ccode%3Efunc%20main()%20%7B%5Cn%20%20%2F%2F%20%E5%B1%95%E5%BC%80%20g%20%3A%3D%20G()%5Cn%20%20%2F%2F%20%3D%26gt%3B%20g%20%3A%3D%20%26%2334%3BG2%26%2334%3B%5Cn%5Cn%20%20%2F%2F%20%E5%B1%95%E5%BC%80%20fmt.Println(g)%5Cn%20%20%2F%2F%20%3D%26gt%3B%20%E7%9B%B8%E5%85%B3%5Cn%7D%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%22111%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E5%8F%AF%E8%A7%81%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E5%92%8C%20%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG2%3C%2Fspan%3E%3C%2Fspan%3E%20%E5%87%BD%E6%95%B0%E5%8E%9F%E6%9C%AC%E6%89%A7%E8%A1%8C%E6%97%B6%E5%80%99%E5%B8%A6%E6%9D%A5%E5%87%BD%E6%95%B0%E6%A0%88%E7%94%B3%E8%AF%B7%E5%9B%9E%E6%94%B6%EF%BC%8C%E4%BC%98%E5%8C%96%E8%BF%87%E5%90%8E%E5%B0%86%E4%B8%8D%E5%86%8D%E6%9C%89%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%22112%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E8%BF%99%E9%87%8C%E6%88%91%E4%BB%AC%E6%89%A7%E8%A1%8C%20%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3Ego%20run%20-gcflags%3D%26%2334%3B-m%20-m%26%2334%3B%20main.go%3C%2Fspan%3E%3C%2Fspan%3E%20%E6%9D%A5%E6%9F%A5%E7%9C%8B%E7%BC%96%E8%AF%91%E5%9C%A8%E8%BF%9B%E8%A1%8C%E4%BB%A5%E4%B8%8A%E4%BB%A3%E7%A0%81%E7%9A%84%E5%86%85%E8%81%94%E4%BC%98%E5%8C%96%E3%80%82%3C%2Fp%3E%3Cpre%3E%3Ccode%3E%E2%98%81%EF%B8%8F%20%20test%20%20go%20run%20-gcflags%3D%26%2334%3B-m%20-m%26%2334%3B%20main.go%5Cn%23%20command-line-arguments%5Cn.%2Fmain.go%3A5%3A6%3A%20can%20inline%20G2%20as%3A%20func()%20string%20%7B%20return%20%26%2334%3BG2%26%2334%3B%20%7D%20.%2Fmain.go%3A9%3A6%3A%20can%20inline%20G%20as%3A%20func()%20string%20%7B%20return%20G2()%20%7D%20.%2Fmain.go%3A10%3A11%3A%20inlining%20call%20to%20G2%20func()%20string%20%7B%20return%20%26%2334%3BG2%26%2334%3B%20%7D%20.%2Fmain.go%3A13%3A6%3A%20cannot%20inline%20main%3A%20function%20too%20complex%3A%20cost%2087%20exceeds%20budget%2080%5Cn.%2Fmain.go%3A14%3A8%3A%20inlining%20call%20to%20G%20func()%20string%20%7B%20return%20G2()%20%7D%20.%2Fmain.go%3A14%3A8%3A%20inlining%20call%20to%20G2%20func()%20string%20%7B%20return%20%26%2334%3BG2%26%2334%3B%20%7D%20.%2Fmain.go%3A15%3A13%3A%20inlining%20call%20to%20fmt.Println%20func(...interface%20%7B%7D)%20(int%2C%20error)%20%7B%20var%20fmt..autotmp_3%20int%3B%20fmt..autotmp_3%20%3D%20%26lt%3BN%26gt%3B%3B%20var%20fmt..autotmp_4%20error%3B%20fmt..autotmp_4%20%3D%20%26lt%3BN%26gt%3B%3B%20fmt..autotmp_3%2C%20fmt..autotmp_4%20%3D%20fmt.Fprintln(io.Writer(os.Stdout)%2C%20fmt.a...)%3B%20return%20fmt..autotmp_3%2C%20fmt..autotmp_4%20%7D%5Cn.%2Fmain.go%3A15%3A13%3A%20g%20escapes%20to%20heap%20.%2Fmain.go%3A15%3A13%3A%20main%20%5B%5Dinterface%20%7B%7D%20literal%20does%20not%20escape%5Cn.%2Fmain.go%3A15%3A13%3A%20io.Writer(os.Stdout)%20escapes%20to%20heap%20%26lt%3Bautogenerated%26gt%3B%3A1%3A%20(*File).close%20.this%20does%20not%20escape%20G2%5Cn%3C%2Fcode%3E%3C%2Fpre%3E%3Cp%20data-track%3D%5C%22114%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%BB%8E%E6%89%93%E5%8D%B0%E5%87%BA%E7%9A%84%E5%86%85%E5%AE%B9%E5%8F%AF%E4%BB%A5%E7%9C%8B%EF%BC%8C%3C%2Fspan%3E%3Cspan%20style%3D%5C%22color%3A%20%231E6BB8%3B%20--tt-darkmode-color%3A%20%23227AD2%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23E8E8E8%3B%20--tt-darkmode-bgcolor%3A%20%23292929%3B%5C%22%3EG2%5C%5CG%5C%5Cfmt.Println%3C%2Fspan%3E%3C%2Fspan%3E%20%E9%83%BD%E8%A2%AB%E5%86%85%E8%81%94%E4%BA%86%E3%80%82%3C%2Fp%3E%3Cp%20data-track%3D%5C%22115%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%233E4753%3B%20--tt-darkmode-color%3A%20%238F9BAB%3B%5C%22%3E%E4%B8%8A%E9%9D%A2%E6%8F%90%E5%88%B0%E4%BA%86%20gomokey%20%E6%89%93%E6%A1%A9%E7%9A%84%E9%80%BB%E8%BE%91%EF%BC%8C%E5%AE%83%E6%98%AF%E5%9C%A8%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E7%9A%84%E6%97%B6%E5%80%99%E9%80%9A%E8%BF%87%E6%9C%BA%E5%99%A8%E6%8C%87%E4%BB%A4%E5%B0%86%E5%87%BD%E6%95%B0%E7%9A%84%E6%8C%87%E5%90%91%E6%9B%BF%E6%8D%A2%E4%BA%86%E3%80%82%E7%94%B1%E4%BA%8E%E5%87%BD%E6%95%B0%E7%BC%96%E8%AF%91%E5%90%8E%E8%A2%AB%E5%86%85%E8%81%94%EF%BC%8C%E5%AE%9E%E9%99%85%E4%B8%8A%E4%B8%8D%E5%AD%98%E5%9C%A8%E5%87%BD%E6%95%B0%E7%9A%84%E8%B0%83%E7%94%A8%EF%BC%8C%E5%AF%BC%E8%87%B4%E5%8D%95%E6%B5%8B%E6%89%A7%E8%A1%8C%E4%B8%8D%E9%80%9A%E8%BF%87%EF%BC%8C%E8%BF%99%E4%B9%9F%E6%98%AF%E5%86%85%E8%81%94%E5%AF%BC%E8%87%B4%20gomonkey%20%E6%89%93%E6%A1%A9%E6%97%A0%E6%95%88%E7%9A%84%E9%97%AE%E9%A2%98%E6%89%80%E5%9C%A8%E3%80%82%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20style%3D%5C%22text-align%3A%20center%3B%5C%22%20data-track%3D%5C%22120%5C%22%3E%3Cspan%20style%3D%5C%22letter-spacing%3A%201px%3B%5C%22%3E%3Cstrong%3E%3Cspan%20style%3D%5C%22color%3A%20%23FFFFFF%3B%20--tt-darkmode-color%3A%20%23FFFFFF%3B%5C%22%3E%3Cspan%20style%3D%5C%22background-color%3A%20%23138BDE%3B%20--tt-darkmode-bgcolor%3A%20%23138BDE%3B%5C%22%3E%E5%86%99%E5%9C%A8%E6%9C%80%E5%90%8E%3C%2Fspan%3E%3C%2Fspan%3E%3C%2Fstrong%3E%3C%2Fspan%3E%3C%2Fp%3E%3Cp%20data-track%3D%5C%22121%5C%22%3E%3Cspan%20style%3D%5C%22color%3A%20%23111111%3B%20--tt-darkmode-color%3A%20%23A3A3A3%3B%5C%22%3EFreemen%20App%E6%98%AF%E4%B8%80%E6%AC%BE%E4%B8%93%E6%B3%A8%E4%BA%8EIT%E7%A8%8B%E5%BA%8F%E5%91%98%E6%B1%82%E8%81%8C%E6%8B%9B%E8%81%98%E7%9A%84%E4%B8%80%E4%B8%AA%E6%B1%82%E8%81%8C%E5%B9%B3%E5%8F%B0%EF%BC%8C%E6%97%A8%E5%9C%A8%E5%B8%AE%E5%8A%A9IT%E6%8A%80%E6%9C%AF%E5%B7%A5%E4%BD%9C%E8%80%85%E8%83%BD%E6%9B%B4%E5%A5%BD%E6%9B%B4%E5%BF%AB%E5%85%A5%E8%81%8C%E5%8F%8A%E5%8A%AA%E5%8A%9B%E5%8D%8F%E8%B0%83IT%E6%8A%80%E6%9C%AF%E8%80%85%E5%B7%A5%E4%BD%9C%E5%92%8C%E7%94%9F%E6%B4%BB%E7%9A%84%E5%85%B3%E7%B3%BB%EF%BC%8C%E8%AE%A9%E5%B7%A5%E4%BD%9C%E6%9B%B4%E8%87%AA%E7%94%B1%EF%BC%81%3C%2Fspan%3E%3C%2Fp%3E%3Cdiv%20class%3D%5C%22pgc-img%5C%22%3E%3Cimg%20src%3D%5C%22https%3A%2F%2Fp3-sign.toutiaoimg.com%2Ftos-cn-i-qvj2lq49k0%2F4f76255f3b074051aac9d049e5fe72ea~tplv-tt-origin-web%3Agif.jpeg%3F_iz%3D58558%26from%3Darticle.pc_detail%26lk3s%3D953192f4%26x-expires%3D1734609857%26x-signature%3DHmsxOGVN213kq4mh2c3SQZOiCLQ%253D%5C%22%20img_width%3D%5C%221024%5C%22%20img_height%3D%5C%22512%5C%22%20image_type%3D%5C%221%5C%22%20mime_type%3D%5C%22image%2Fpng%5C%22%20web_uri%3D%5C%22tos-cn-i-qvj2lq49k0%2F4f76255f3b074051aac9d049e5fe72ea%5C%22%3E%3Cp%20class%3D%5C%22pgc-img-caption%5C%22%3E%3C%2Fp%3E%3C%2Fdiv%3E%3Cp%20data-track%3D%5C%22123%5C%22%3E%E6%9C%AC%E6%96%87%E8%BD%AC%E8%BD%BD%E8%87%AA%3Cspan%20style%3D%5C%22letter-spacing%3A%201px%3B%5C%22%3E%E8%85%BE%E8%AE%AF%E6%8A%80%E6%9C%AF%E5%B7%A5%E7%A8%8B%3C%2Fspan%3E%3C%2Fp%3E%22%2C%22imageList%22%3A%5B%22https%3A%2F%2Fp3-sign.toutiaoimg.com%2Ftos-cn-i-qvj2lq49k0%2Fe108da3ebb3741d7af7665d5a59ff21c~tplv-tt-origin-web%3Agif.jpeg%3F_iz%3D58558%26from%3Darticle.pc_detail%26lk3s%3D953192f4%26x-expires%3D1734609857%26x-signature%3DVvb2b50Q84K4UtpZubecV0HS6HQ%253D%22%2C%22https%3A%2F%2Fp3-sign.toutiaoimg.com%2Ftos-cn-i-qvj2lq49k0%2F2f1220bbf1064c8a9eb83d7188697332~tplv-tt-origin-web%3Agif.jpeg%3F_iz%3D58558%26from%3Darticle.pc_detail%26lk3s%3D953192f4%26x-expires%3D1734609857%26x-signature%3D6LvsZwDUwu%252BW76ZO0A0u9onC%252BDQ%253D%22%2C%22https%3A%2F%2Fp3-sign.toutiaoimg.com%2Ftos-cn-i-qvj2lq49k0%2F4f76255f3b074051aac9d049e5fe72ea~tplv-tt-origin-web%3Agif.jpeg%3F_iz%3D58558%26from%3Darticle.pc_detail%26lk3s%3D953192f4%26x-expires%3D1734609857%26x-signature%3DHmsxOGVN213kq4mh2c3SQZOiCLQ%253D%22%5D%2C%22mediaInfo%22%3A%7B%22userId%22%3A%22MS4wLjABAAAAJOciZkc9eBL9yaD0sqJ6EvcVuBksXQMzilpmr2mk6bGNzfFMOA1wkQR9ctLoqvqA%22%2C%22unsafeUserId%22%3A%223404510121171997%22%2C%22name%22%3A%22Freemen%E7%A8%8B%E5%BA%8F%E5%91%98%E6%8B%9B%E8%81%98app%22%2C%22avatarUrl%22%3A%22https%3A%2F%2Fsf3-cdn-tos.toutiaostatic.com%2Fimg%2Fuser-avatar%2F7c3277bf677f5aaccc5e9d913fab74bf~300x300.image%22%2C%22description%22%3A%22%22%2C%22userVerified%22%3A1%7D%2C%22seoTDK%22%3A%7B%22title%22%3A%22%E2%80%8B%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%20Golang%20%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%20-%20%E4%BB%8A%E6%97%A5%E5%A4%B4%E6%9D%A1%22%2C%22description%22%3A%22%E5%BC%95%E5%85%A5%E9%9A%8F%E7%9D%80%E5%B7%A5%E7%A8%8B%E5%8C%96%E5%BC%80%E5%8F%91%E7%9A%84%E5%86%85%E5%A4%A7%E5%8A%9B%E7%9A%84%E6%8E%A8%E5%B9%BF%EF%BC%8C%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E8%B6%8A%E6%9D%A5%E8%B6%8A%E5%8F%97%E5%88%B0%E5%B9%BF%E5%A4%A7%E5%BC%80%E5%8F%91%E8%80%85%E7%9A%84%E9%87%8D%E8%A7%86%E3%80%82%E5%9C%A8%E5%AD%A6%E4%B9%A0%E7%9A%84%E8%BF%87%E7%A8%8B%E4%B8%AD%EF%BC%8C%E5%8F%91%E7%8E%B0%E7%BD%91%E4%B8%8A%E9%92%88%E5%AF%B9%20Golang%20%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E5%A4%A7%E5%A4%9A%E4%BB%8E%E7%90%86%E8%AE%BA%E8%A7%92%E5%BA%A6%E5%87%BA%E5%8F%91%E4%BB%8B%E7%BB%8D%EF%BC%8C%E7%BC%BA%E4%B9%8F%E5%AE%8C%E6%95%B4%E7%9A%84%E5%AE%9E%E4%BE%8B%E8%AF%B4%E6%98%8E%EF%BC%8C%E6%99%A6%E6%B6%A9%E9%9A%BE%E6%87%82%E7%9A%84%20API%20%E8%AE%A9%E5%88%9D%E5%AD%A6%E6%8E%A5%E8%A7%A6%E8%80%85%E9%9A%BE%E4%BB%A5%E4%B8%8B%E6%89%8B%E3%80%82%22%2C%22keywords%22%3A%22Redis%2CJSON%2C%E6%95%B0%E6%8D%AE%E5%BA%93%22%2C%22publishTimestamp%22%3A%221675131752%22%2C%22modifiedTimestamp%22%3A%221732295492%22%7D%2C%22cover%22%3A%22https%3A%2F%2Fp3-sign.toutiaoimg.com%2Ftos-cn-i-qvj2lq49k0%2Fdaacfeb901cb47cb8e5075aeedbff19e~tplv-tt-shrink-asy2-web%3A640%3A0%3A5aS05p2hQEZyZWVtZW7nqIvluo_lkZjmi5vogZhhcHA%3D%3Agif.jpeg%3F_iz%3D58558%26from%3Darticle.pc_detail%26lk3s%3D953192f4%26x-expires%3D1734609857%26x-signature%3DscoITv0VcHY%252BEtz9UlBpf9nBIRo%253D%22%2C%22logId%22%3A%2220241212200417150715FEE0C436C97040%22%2C%22sylpageConfig%22%3A%7B%22card%22%3A%7B%22id%22%3A%22%22%7D%7D%2C%22identity%22%3A%7B%22web_id%22%3A%227447494372893656587%22%2C%22user_is_login%22%3Afalse%7D%2C%22abtestInfo%22%3A%7B%22rsp_type%22%3A5%2C%22version_name%22%3A%224938400%2C8813385%22%2C%22parameters%22%3A%7B%22filter%22%3A%7B%22debug_enable_pc_small_video%22%3Afalse%2C%22enable_pc_small_video%22%3Atrue%7D%2C%22home_nav_conf%22%3A%7B%22dcd_out%22%3A1%7D%2C%22optimus%22%3A%7B%22rule_rank_rules%22%3A%22ranking_rule_list%20%7B%5Cn%20%20id%3A%201221233%5Cn%20priority%3A%200%5Cn%20tags%3A%20%5C%2212123%5C%22%5Cn%20%20enabled%3A%20true%5Cn%20%20type%3A%20CARD%5Cn%20%20card_rule%20%7B%5Cn%20size%3A%202%5Cn%20type%3A%20SAME_SLOT%20%5Cn%7D%5Cn%20%7D%5Cn%20ranking_rule_list%20%7B%5Cn%20%20id%3A%2020458%5Cn%20%20priority%3A%203%5Cn%20%20enabled%3A%20true%5Cn%20%20category%3A%2020458%5Cn%20%20type%3A%20WINDOW%5Cn%20%20window_rule%20%7B%5Cn%20%20%20%20type%3A%20SLIDE%5Cn%20%20%20%20size%3A%203%5Cn%20%20%20%20max%3A%201%5Cn%20%20%7D%5Cn%7D%5Cn%20ranking_rule_list%20%7B%5Cn%20%20id%3A%201111024%5Cn%20priority%3A%200%5Cn%20tags%3A%20%5C%2211024%5C%22%5Cn%20%20enabled%3A%20true%5Cn%20%20type%3A%20CARD%5Cn%20%20card_rule%20%7B%5Cn%20size%3A%206%5Cn%20type%3A%20SAME_SLOT%20%5Cn%7D%5Cn%20%7D%22%7D%2C%22page_upgrade%22%3A%7B%22new_profile%22%3Atrue%2C%22video_double_column%22%3Atrue%7D%2C%22recall%22%3A%7B%22debug_filter_reason_list%22%3A%5B%5D%2C%22debug_recall_reason_list%22%3A%5B70%2C71%2C72%2C73%2C80%2C83%5D%2C%22enable_debug_filter_reason%22%3Atrue%2C%22enable_debug_recall_reason%22%3Atrue%2C%22friend_feed%22%3A%7B%22control_nums%22%3A1500%2C%22count%22%3A1000%2C%22enable%22%3Atrue%2C%22enable_cpp_friend_feed%22%3Atrue%2C%22enable_friend_feed_container_filter%22%3Atrue%2C%22enable_group_status_filter%22%3Atrue%2C%22params%22%3A%7B%7D%2C%22top_k%22%3A10%2C%22use_new_friend_recall%22%3Atrue%2C%22valid_group_source%22%3A%5B2%2C5%2C15%2C23%2C16%2C19%2C21%2C132%5D%2C%22weight%22%3A20%7D%7D%2C%22seraph%22%3A%7B%22rule_rank_rules_pc_small%22%3A%22%5Cn%20%20%20%20%20%20ranking_rule_list%20%7B%5Cn%20%20%20%20%20%20%20%20%20id%3A%2022124%20%5Cn%20%20%20%20%20%20%20%20%20priority%3A%200%20%5Cn%20%20%20%20%20%20%20%20%20tags%3A%20%5C%2222124%5C%22%20%5Cn%20%20%20%20%20%20%20%20%20enabled%3A%20true%20%5Cn%20%20%20%20%20%20%20%20%20type%3A%20CARD%20%5Cn%20%20%20%20%20%20%20%20%20card_rule%20%7B%20%5Cn%20%20%20%20%20%20%20%20%20size%3A%206%20%5Cn%20%20%20%20%20%20%20%20%20num_cards%3A%201%5Cn%20%20%20%20%20%20%20%20%20type%3A%20SAME_SLOT%20%5Cn%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%22%2C%22rule_rank_rules_pc_small_window%22%3A%22%5Cn%20%20%20%20%20%20ranking_rule_list%20%7B%5Cn%20%20%20%20id%3A%20222124%5Cn%20%20%20priority%3A%200%5Cn%20%20%20tags%3A%20%5C%2222124%5C%22%5Cn%20%20%20%20enabled%3A%20false%5Cn%20%20%20%20type%3A%20WINDOW%5Cn%20%20%20%20window_rule%20%7B%5Cn%20%20%20type%3A%20SLIDE%20%5Cn%20%20%20size%3A%2012%20%5Cn%20%20%20max%3A%206%20%5Cn%20%20%20%7D%5Cn%20%20%20%7D%22%7D%2C%22small_sort%22%3A%7B%22enable_filter_zhanwai%22%3Atrue%2C%22filter_genre_plog%22%3Afalse%2C%22filter_genre_small%22%3Afalse%2C%22skip_small_app_version_filter%22%3Afalse%2C%22skip_small_genre_filter%22%3Afalse%7D%2C%22sort%22%3A%7B%22allowed_ticai%22%3A%5B%22forum_post%22%2C%22pgc_text%22%2C%22pgc_video%22%2C%22short_video%22%5D%2C%22enable_optimus_gen_pc_mv_card%22%3Atrue%2C%22enable_optimus_gen_pc_sv_card%22%3Atrue%2C%22enable_pc_skip_app_smallvideo_card%22%3Atrue%7D%2C%22stream%22%3A%7B%22disable_related%22%3Atrue%2C%22enable_ads_sdk%22%3Atrue%2C%22enable_ads_sdk_pack%22%3Atrue%7D%2C%22ugc_sort%22%3A%7B%22expore_smallvideo%22%3Atrue%7D%2C%22video_channel%22%3A%7B%22rank%22%3A5%2C%22use_feed%22%3A1%7D%7D%2C%22env_flag%22%3A0%2C%22ns_parameters%22%3A%7B%7D%2C%22object_parameters%22%3A%7B%7D%7D%2C%22localCityInfo%22%3A%7B%22name%22%3A%22%E8%B4%BA%E5%B7%9E%22%2C%22code%22%3A%22451100%22%2C%22channelId%22%3A3202164680%7D%2C%22voteLink%22%3A%5B%7B%22keyword%22%3A%22Us%20Aaj%20Tak%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767723009%22%7D%2C%7B%22keyword%22%3A%22Thori%20Pee%20Layi%20Te%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767673857%22%7D%2C%7B%22keyword%22%3A%22Tetho%20Dil%20Mangya%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767624705%22%7D%2C%7B%22keyword%22%3A%22Sada%20Sarghoday%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767559169%22%7D%2C%7B%22keyword%22%3A%22Laiyan%20Laiyan%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767477249%22%7D%2C%7B%22keyword%22%3A%22Dil%20Sada%20Naal%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767411713%22%7D%2C%7B%22keyword%22%3A%22Beli%20Barna%20Ke%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767346177%22%7D%2C%7B%22keyword%22%3A%22Sajna%20Siwa%20Asan%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767231489%22%7D%2C%7B%22keyword%22%3A%22New%20Qasida%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767149569%22%7D%2C%7B%22keyword%22%3A%22Me%20Raj%20K%22%2C%22type%22%3A%22%22%2C%22url%22%3A%22https%3A%2F%2Fwww.douyin.com%2Fqishui%2Fsong%2F7245958797767067649%22%7D%5D%2C%22grSensitive%22%3Afalse%2C%22showResearch%22%3Afalse%2C%22blockVisibility%22%3A%7B%22hotBoard%22%3Atrue%2C%22hotVideo%22%3Atrue%2C%22relatedRecommend%22%3Atrue%7D%2C%22isGreyTheme%22%3Afalse%2C%22activateConfig%22%3A%7B%22enable%22%3Atrue%2C%22bannerInfo%22%3A%7B%22title%22%3A%22%E6%89%AB%E7%A0%81%E4%B8%8B%E8%BD%BD%E4%BB%8A%E6%97%A5%E5%A4%B4%E6%9D%A1APP%22%2C%22desc%22%3A%22%E7%9C%8B%E6%9C%80%E6%96%B0%E3%80%81%E6%9C%80%E7%83%AD%E8%B5%84%E8%AE%AF%E5%86%85%E5%AE%B9%22%2C%22qrcodeUrl%22%3A%22https%3A%2F%2Flf3-static.bytednsdoc.com%2Fobj%2Feden-cn%2Fbeeh7nuvjvho%2Fqrcode.png%22%7D%2C%22popupInfo%22%3A%7B%22title%22%3A%22%E6%89%AB%E7%A0%81%E4%B8%8B%E8%BD%BD%E4%BB%8A%E6%97%A5%E5%A4%B4%E6%9D%A1%22%2C%22qrcodeUrl%22%3A%22https%3A%2F%2Flf3-static.bytednsdoc.com%2Fobj%2Feden-cn%2Fbeeh7nuvjvho%2Fqrcode.png%22%7D%2C%22toolPopConfig%22%3A%7B%22permanent%22%3Atrue%7D%7D%2C%22searchBot%22%3Anull%2C%22commentInfo%22%3Anull%2C%22detailHotList%22%3Anull%2C%22detailFeedList%22%3Anull%7D%7D
reg := regexp.MustCompile(pattern) return reg.MatchString(email) } // 通过 redis 拉取对应用户的资料信息 func getPersonDetailRedis(username string) (*PersonDetail, error) { result := &PersonDetail{} client, err := redis.Dial("tcp", ":6379") defer client.Close() data, err := redis.Bytes(client.Do("GET", username)) if err != nil { return nil, err } err = json.Unmarshal(data, result) if err != nil { return nil, err } return result, nil } // 拉取用户资料信息并校验 func GetPersonDetail(username string) (*PersonDetail, error) { // 检查用户名是否有效 if ok := checkUsername(username); !ok { return nil, errors.New("invalid username") } // 从 redis 接口获取信息 detail, err := getPersonDetailRedis(username) if err != nil { return nil, err } // 校验 if ok := checkEmail(detail.Email); !ok { return nil, errors.New("invalid email") } return detail, nil }

软件开发过程中,后台单元测试对于保证代码品质至关重要。然而,它所涉及到的诸多逻辑和技术细节往往让人感到困扰。这包括不同层级的逻辑检验、参数核对,以及众多框架的使用等多个复杂方面。本文将对此进行详细剖析。

后台单测的核心层面验证

package unit
import (
  "reflect"
  "testing"
)
func TestGetPersonDetail(t *testing.T) {
 type args struct {
  username string
 }
 tests := []struct {
  name    string
  args    args
  want    *PersonDetail
  wantErr bool
 }{
  // TODO: Add test cases.
 }
 for _, tt := range tests {
  t.Run(tt.name, func(t *testing.T) {
   got, err := GetPersonDetail(tt.args.username)
   if (err != nil) != tt.wantErr {
    t.Errorf("GetPersonDetail() error = %v, wantErr %v", err, tt.wantErr)
    return
   }
   if !reflect.DeepEqual(got, tt.want) {
    t.Errorf("GetPersonDetail() got = %v, want %v", got, tt.want)
   }
  })
 }
}

根据职责要求进行后台的单项测试,首要任务是核实验证层和DAO层的逻辑正确性。在具体工作中,以某公司的开发项目为例,开发人员发现层与层之间的数据流动对产品功能有着直接的影响。此外,层的参数检查同样需要在单测中加以关注。以登录功能为例,如果用户名的参数校验没有经过单测,可能会引发安全风险,如恶意登录等问题。这些问题在后台测试中是必须重视的。

后台测试时,需明确了解验证的重点,确保各层逻辑准确无误,参数校验正确,不能草率行事。

package unit
import (
  "github.com/stretchr/testify/assert" // 这里引入了 testify
  "reflect"
  "testing"
)
func TestGetPersonDetail(t *testing.T) {
 type args struct {
  username string
 }
 tests := []struct {
  name    string
  args    args
  want    *PersonDetail
  wantErr bool
 }{
  // TODO: Add test cases.
 }
 for _, tt := range tests {
  got, err := GetPersonDetail(tt.args.username)
  // 改写这里断言的方式即可
  assert.Equal(t, tt.want, got)
  assert.Equal(t, tt.wantErr, err != nil)
 }
}

func Test_checkEmail(t *testing.T) {
 type args struct {
  email string
 }
 tests := []struct {
  name string
  args args
  want bool
 }{
  {
   name: "email valid",
   args: args{
    email: "1234567@qq.com",
   },
   want: true,
  },
  {
   name: "email invalid",
   args: args{
    email: "test.com",
   },
   want: false,
  },
 }
 for _, tt := range tests {
  got := checkEmail(tt.args.email)
  assert.Equal(t, tt.want, got)
 }
}

单元测试的本质与范围

// 拉取用户资料信息并校验
func GetPersonDetail(username string) (*PersonDetail, error) {
 // 检查用户名是否有效
 if ok := checkUsername(username); !ok {
  return nil, errors.New("invalid username")
 }
 // 从 redis 接口获取信息
 detail, err := getPersonDetailRedis(username)
 if err != nil {
  return nil, err
 }
 // 校验
 if ok := checkEmail(detail.Email); !ok {
  return nil, errors.New("invalid email")
 }
 return detail, nil
}

单元测试主要针对单一函数展开,特别注重其内部运作机制。在诸如金融项目这样的实际应用中,对于涉及资金计算的函数进行单元测试时,必须确保其内部逻辑的精确无误。至于网络连接和数据库操作等外部行为,需要采取模拟方法进行处理。这样做的原因在于,单元测试的目的是检验函数自身的功能,而与函数逻辑无关的外部网络波动和数据库服务器状态不应影响测试结果。

func TestGetPersonDetail(t *testing.T) {
 type args struct {
  username string
 }
 tests := []struct {
  name    string
  args    args
  want    *PersonDetail
  wantErr bool
 }{
  {name: "invalid username", args: args{username: "steven xxx"}, want: nil, wantErr: true},
  {name: "invalid email", args: args{username: "invalid_email"}, want: nil, wantErr: true},
  {name: "throw err", args: args{username: "throw_err"}, want: nil, wantErr: true},
  {name: "valid return", args: args{username: "steven"}, want: &PersonDetail{Username: "steven", Email: "12345678@qq.com"}, wantErr: false},
 }
 // 为函数打桩序列
 // 使用 gomonkey 打函数桩序列
 // 第一个用例不会调用 getPersonDetailRedis,所以只需要 3 个值
 outputs := []gomonkey.OutputCell{
  {
   Values: gomonkey.Params{&PersonDetail{Username: "invalid_email", Email: "test.com"}, nil},
  },
  {
   Values: gomonkey.Params{nil, errors.New("request err")},
  },
  {
   Values: gomonkey.Params{&PersonDetail{Username: "steven", Email: "12345678@qq.com"}, nil},
  },
 }
 patches := gomonkey.ApplyFuncSeq(getPersonDetailRedis, outputs)
 // 执行完毕后释放桩序列
 defer patches.Reset()
 for _, tt := range tests {
  got, err := GetPersonDetail(tt.args.username)
  assert.Equal(t, tt.want, got)
  assert.Equal(t, tt.wantErr, err != nil)
 }
}

常常,开发者会弄混单元测试的边界,引入了外部因素。我们必须清楚单元测试的真正含义,关键在于只关注内部逻辑的检验。

单测模板代码的相关操作

// 通过 redis 拉取对应用户的资料信息
func getPersonDetailRedis(username string) (*PersonDetail, error) {
 result := &PersonDetail{}
 client, err := redis.Dial("tcp", ":6379")
 defer client.Close()
 data, err := redis.Bytes(client.Do("GET", username))
 if err != nil {
  return nil, err
 }
 err = json.Unmarshal(data, result)
 if err != nil {
  return nil, err
 }
 return result, nil
}

所生成的测试模板代码遵循官方框架。以某开源项目为实例,在实际应用中,人们常将其调整为便于断言的形式。这种调整并不繁琐,只需添加特定内容,并对test函数末尾的断言代码进行修改即可。以一个数据处理函数为例,这样的调整可以使测试结果的判定更为精确和高效。

初学者在执行这类任务时常常感到迷茫。因此,我们必须透彻掌握这类模板代码的使用方法,以便更有效地开展单元测试。

// redis 包中关于 Conn 的定义
// Conn represents a connection to a Redis server.
type Conn interface {
 // Close closes the connection.
 Close() error
 // Err returns a non-nil value when the connection is not usable.
 Err() error
 // Do sends a command to the server and returns the received reply.
 Do(commandName string, args ...interface{}) (reply interface{}, err error)
 // Send writes the command to the client's output buffer.
 Send(commandName string, args ...interface{}) error
 // Flush flushes the output buffer to the Redis server.
 Flush() error
 // Receive receives a single reply from the Redis server
 Receive() (reply interface{}, err error)
}
// 实现接口
type Client struct {}
func (c *Client) Close() error {
  return nil
}
func (c *Client) Err() error {
  return nil
}
func (c *Client) Do(commandName string, args ...interface{}) (interface{}, error) {
  return nil, nil
}
func (c *Client) Send(commandName string, args ...interface{}) error {
  return nil
}
func (c *Client) Flush() error {
  return nil
}
func (c *Client) Receive() (interface{}, error) {
  return nil, nil
}
// 实现接口
type Client struct {}
func (c *Client) Close() error {
 return nil
}
func (c *Client) Err() error {
 return nil
}
func (c *Client) Do(commandName string, args ...interface{}) (interface{}, error) {
 return nil, nil
}
func (c *Client) Send(commandName string, args ...interface{}) error {
 return nil
}
func (c *Client) Flush() error {
 return nil
}
func (c *Client) Receive() (interface{}, error) {
 return nil, nil
}
// 进行测试
func test() {
 c := &Client{}
 gomonkey.ApplyFunc(redis.Dial, func(_ string, _ string, _ ...redis.DialOption) (redis.Conn, error) {
  return c, nil
 })
 gomonkey.ApplyMethod(reflect.TypeOf(c), "Do", func(commandName string, args ...interface{}) (interface{}, error) {
  var result interface{}
  return result, nil
 })
}

完全覆盖函数的测试方法

# 打开终端后依次执行
go get -u github.com/golang/mock/gomock
go install github.com/golang/mock/mockgen
# 备注说明,很重要!!!
# 安装完成之后,执行 mockgen 看命令是否生效 # 如果显示命令无效,请找到本机的 GOPATH 安装目录下的 bin 文件夹是否有 mockgen 二进制文件
# GOPATH 可以执行 go env 命令找到
# 如果命令无效但是 GOPATH 路径下的 bin 文件夹中存在 mockgen,请将 GOPATH 下 bin 文件夹的绝对路径添加到全局 PATH 中

要实现一个函数的全面测试,比如针对一个用户权限管理的函数,必须操控相关函数的输出,保证后续代码能够顺利执行。在电商后台的开发中,这一环节尤为关键。此外,在运用桩序列时,必须细致研究单元测试案例与序列值之间的联系。

mockgen -destination=mock_redis.go -package=unit github.com/gomodule/redigo/redis Conn
# 更多指令参考:https://github.com/golang/mock#flags

对全面覆盖的函数进行测试并非易事,需要仔细考量众多相关函数的细节,这样才能确保测试效果符合预期。

func Test_getPersonDetailRedis(t *testing.T) {
 tests := []struct {
  name    string
  want    *PersonDetail
  wantErr bool
 }{
  {name: "redis.Do err", want: nil, wantErr: true},
  {name: "json.Unmarshal err", want: nil, wantErr: true},
  {name: "success", want: &PersonDetail{
   Username: "steven",
   Email:    "1234567@qq.com",
  }, wantErr: false},
 }
 ctrl := gomock.NewController(t)
 defer ctrl.Finish()
 // 1. 生成符合 redis.Conn 接口的 mockConn
 mockConn := NewMockConn(ctrl)
 // 2. 给接口打桩序列
 gomock.InOrder(
  mockConn.EXPECT().Do("GET", gomock.Any()).Return("", errors.New("redis.Do err")),
  mockConn.EXPECT().Close().Return(nil),
  mockConn.EXPECT().Do("GET", gomock.Any()).Return("123", nil),
  mockConn.EXPECT().Close().Return(nil),
  mockConn.EXPECT().Do("GET", gomock.Any()).Return([]byte(`{"username": "steven", "email": "1234567@qq.com"}`), nil),
  mockConn.EXPECT().Close().Return(nil),
 )
 // 3. 给 redis.Dail 函数打桩
 outputs := []gomonkey.OutputCell{
  {
   Values: gomonkey.Params{mockConn, nil},
   Times:  3, // 3 个用例
  },
 }
 patches := gomonkey.ApplyFuncSeq(redis.Dial, outputs)
 // 执行完毕之后释放桩序列
 defer patches.Reset()
 // 4. 断言
 for _, tt := range tests {
  actual, err := getPersonDetailRedis(tt.name)
  // 注意,equal 函数能够对结构体进行 deap diff
  assert.Equal(t, tt.want, actual)
  assert.Equal(t, tt.wantErr, err != nil)
 }
}

函数和方法的Mock操作

进行打桩操作时,需先定义结构体并实现其接口所要求的方法。在面向对象编程模式中,理解类与接口之间的关系相对简单。然而,在Go语言中,由于语言特性,一旦函数或方法的逻辑声明完成,就很难通过编码进行Mock处理,这对单元测试构成了不小的难题。例如,对一个加密函数进行Mock操作尤其复杂。

☁️  go_unit_test [master]   go test -v -cover
=== RUN   TestGetPersonDetail
--- PASS: TestGetPersonDetail (0.00s)
=== RUN   Test_checkEmail
--- PASS: Test_checkEmail (0.00s)
=== RUN   Test_checkUsername
--- PASS: Test_checkUsername (0.00s)
=== RUN   Test_getPersonDetailRedis
--- PASS: Test_getPersonDetailRedis (0.00s)
PASS
coverage: 60.8% of statements
ok      unit    0.131s

遇到这样的问题,我们应当探索怎样的解决途径?这确实是个值得每一位开发者深思的问题。

内联对单测的影响

☁️  go_unit_test [master]   go test -cover -v  -run Test_getPersonDetailRedis
=== RUN   Test_getPersonDetailRedis
--- PASS: Test_getPersonDetailRedis (0.00s)
PASS
coverage: 41.9% of statements
ok      unit    0.369s

编译时内联操作会影响单元测试。一旦函数被内联,调用就消失了,这在许多架构代码中常引发问题。例如,在某个邮件系统的后台服务开发中,函数内联导致单测无法通过。Go语言对内联函数有规定,含有闭包、for等关键词的函数通常不会内联。执行gotest命令时,通过添加相应参数,可以避免编译器优化内联造成的单测问题。

如何有效协调内联测试与独立测试,提升测试效能?期待大家在评论区交流心得,同时,恳请点赞及转发文章,让更多人认识并关注后台独立测试。

手把手教你如何进行 Golang 单元测试:详细步骤与最佳实践

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

七爪网 行业资讯 手把手教你如何进行 Golang 单元测试:详细步骤与最佳实践 https://www.7claw.com/2802378.html

七爪网源码交易平台

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务