Can I get some help using httptest.Server

xuanbao · · 463 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>As the title suggests I&#39;m using <a href="https://golang.org/pkg/net/http/httptest/" rel="nofollow">http/httptest.Server</a> to test a small app I am writing to help me learn Go.</p> <p>The project can be found here: <a href="https://github.com/tjheslin1/YAHNCrawler" rel="nofollow">YAHNCrawler</a>. It prints the story information of the top stories on Hacker News. I&#39;m striving towards concurrency here.</p> <p>My problem, getting the testServer to handle different url paths:</p> <p>my query code:</p> <pre><code>// query performs a HTTP: GET request to the specified url. // Storing the response&#39;s body in the `result`. // query expects the provided `result` to conform to the query&#39;s repsonse body. func query(url string, result interface{}) *interface{} { resp, err := http.Get(url) check(err) body, err := ioutil.ReadAll(resp.Body) resp.Body.Close() check(err) unmarshalErr := json.Unmarshal(body, result) check(unmarshalErr) return &amp;result } </code></pre> <p>The issue is this method is called twice. Once to get a list of ids of the top stories, the next call queries the information of a story by one of these ids using a different url path.</p> <p>I have tests for each call but I want to do a full end-to-end test of the exported function <code>CrawlTopStories</code>. </p> <p>my test:</p> <pre><code>func TestCrawlTopStories(t *testing.T) { testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, `[ 14223020 ]`) })) defer testServer.Close() CrawlTopStories(testServer.URL) // TODO fail test if not passed } </code></pre> <p>Above in <code>TestCrawlTopStories</code> I have set up the test server to respond with the id of a single story, necessary for the first call. But I need a separate handler to support the second call to &#34;/story/{id}&#34;.</p> <p>Is there a solution where I can reuse the same testServer? Reading httptest.Server.go hasn&#39;t shed any light on this issue, maybe I need to look deeper.</p> <p>Once I have this solved I would like to address this code:</p> <pre><code>storyChan := make(chan *Story, topStoryCount) go func(storyCh chan&lt;- *Story) { for _, topStoryID := range *topStoryIDs { storyCh &lt;- queryStory(&#34;https://hacker-news.firebaseio.com/v0/item/&#34; + strconv.Itoa(topStoryID) + &#34;.json?print=pretty&#34;) time.Sleep(500 * time.Millisecond) } close(storyChan) }(storyChan) .... </code></pre> <p>Ideally I could make each call, concurrently in a separate goroutine, but then I wouldn&#39;t be able to safely close the channel before ranging over it. As I will be querying 500 stories, is there a point in trying to improve this?</p> <p>Many thanks</p> <hr/>**评论:**<br/><br/>HectorJ: <pre><p>So you need routing for your <code>httptest</code> server.</p> <p>Well it&#39;s exactly the same as routing for a <code>http</code> server.</p> <p>For a quick solution, you can use <a href="https://golang.org/pkg/net/http/#ServeMux" rel="nofollow"><code>http.ServeMux</code></a>. Build one, and pass that to <code>httptest.NewServer</code> instead of your <code>http.HandlerFunc</code>.</p> <p>Ultimately, if your test data are 100% static, I think you would be better off storing them in files and using a <a href="https://golang.org/pkg/net/http/#FileServer" rel="nofollow"><code>http.FileServer</code></a></p></pre>tommy144p: <pre><p>Thanks! I&#39;ll look into this. A problem I&#39;ve found with Go is that due to its implicit inheritance, it&#39;s hard to find implementations of interfaces and therefore would likely not have found ServeMux for a long time. Do you know of any method of finding existing implementations?</p></pre>shovelpost: <pre><p><a href="https://docs.google.com/document/d/1_Y9xCEMj5S-7rv2ooHpZNH15JgRT5iM742gJkw5LtmQ/edit" rel="nofollow">Go Guru</a></p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

463 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传