如何模拟 DNS 请求?(miekg/dns)

huangapple go评论154阅读模式
英文:

How to mock a DNS request? (miekg/dns)

问题

我有这段小代码来解释我试图测试的代码库。为了简化问题,我跳过了错误检查。

  1. func lastCNAME(domain string) (lastCNAME string) {
  2. ns := "8.8.8.8:53"
  3. c := dns.Client{}
  4. m := dns.Msg{}
  5. m.SetQuestion(domain, dns.TypeA)
  6. r, _, _ := c.Exchange(&m, ns)
  7. // Last CNAME
  8. for _, ans := range r.Answer {
  9. cname, ok := ans.(*dns.CNAME)
  10. if ok {
  11. lastCNAME = cname.Target
  12. }
  13. }
  14. return lastCNAME
  15. }

如何最好地模拟对名字服务器 8.8.8.8 的 DNS 查询?

这是完整的代码,以防有人感兴趣。

英文:

I have this small piece of code to explain the codebase I'm trying to test. I've skipped checking errors to make the question short.

  1. func lastCNAME(domain string) (lastCNAME string) {
  2. ns := "8.8.8.8:53"
  3. c := dns.Client{}
  4. m := dns.Msg{}
  5. m.SetQuestion(domain, dns.TypeA)
  6. r, _, _ := c.Exchange(&m, ns)
  7. // Last CNAME
  8. for _, ans := range r.Answer {
  9. cname, ok := ans.(*dns.CNAME)
  10. if ok {
  11. lastCNAME = cname.Target
  12. }
  13. }
  14. return lastCNAME
  15. }

What is the best way to mock the dns query to the nameserver 8.8.8.8?

Here is the full code in case anyone's curious.

答案1

得分: 1

你可以为所讨论的函数创建一个接口,并在测试中提供一个存根实现:

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/miekg/dns"
  5. )
  6. type LastCnamer interface {
  7. LastCname(domain string) (lastCname string, err error)
  8. }
  9. type LastCnameResolver string
  10. func (l LastCnameResolver) LastCname(domain string) (lastCname string, err error) {
  11. ns := string(l)
  12. c := dns.Client{}
  13. m := dns.Msg{}
  14. m.SetQuestion(domain, dns.TypeA)
  15. r, _, err := c.Exchange(&m, ns)
  16. if err != nil {
  17. return lastCname, err
  18. }
  19. // Last CNAME
  20. for _, ans := range r.Answer {
  21. cname, ok := ans.(*dns.CNAME)
  22. if ok {
  23. lastCname = cname.Target
  24. }
  25. }
  26. return lastCname, nil
  27. }
  28. type LastCnameStub map[string]string
  29. func (m LastCnameStub) LastCname(domain string) (string, error) {
  30. return m[domain], nil
  31. }
  32. func main() {
  33. m := make(map[string]string)
  34. m["www.linkedin.com."] = "pop-tmu1-alpha.www.linkedin.com."
  35. var l LastCnamer = LastCnameStub(m)
  36. cname, _ := l.LastCname("www.linkedin.com.")
  37. fmt.Println("Stub", cname)
  38. l = LastCnameResolver("8.8.8.8:53")
  39. cname, err := l.LastCname("www.linkedin.com.")
  40. if err != nil {
  41. panic(err)
  42. }
  43. fmt.Println("Resolved", cname)
  44. }

或者,你可以使所讨论的 DNS IP 可配置,以便在测试中进行交换,并启动一个本地 DNS 服务器(github.com/miekg/dns 包中有一个服务器),但这将涉及更多的代码,包括选择一个随机的空闲端口并在测试中使用它。

英文:

You could create an interface for the func in question and provide a stubbed implementation in testing:

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/miekg/dns"
  5. )
  6. type LastCnamer interface {
  7. LastCname(domain string) (lastCname string, err error)
  8. }
  9. type LastCnameResolver string
  10. func (l LastCnameResolver) LastCname(domain string) (lastCname string, err error) {
  11. ns := string(l)
  12. c := dns.Client{}
  13. m := dns.Msg{}
  14. m.SetQuestion(domain, dns.TypeA)
  15. r, _, err := c.Exchange(&m, ns)
  16. if err != nil {
  17. return lastCname, err
  18. }
  19. // Last CNAME
  20. for _, ans := range r.Answer {
  21. cname, ok := ans.(*dns.CNAME)
  22. if ok {
  23. lastCname = cname.Target
  24. }
  25. }
  26. return lastCname, nil
  27. }
  28. type LastCnameStub map[string]string
  29. func (m LastCnameStub) LastCname(domain string) (string, error) {
  30. return m[domain], nil
  31. }
  32. func main() {
  33. m := make(map[string]string)
  34. m["www.linkedin.com."] = "pop-tmu1-alpha.www.linkedin.com."
  35. var l LastCnamer = LastCnameStub(m)
  36. cname, _ := l.LastCname("www.linkedin.com.")
  37. fmt.Println("Stub", cname)
  38. l = LastCnameResolver("8.8.8.8:53")
  39. cname, err := l.LastCname("www.linkedin.com.")
  40. if err != nil {
  41. panic(err)
  42. }
  43. fmt.Println("Resolved", cname)
  44. }

Or you make the DNS IP in question configurable so it can be exchanged in testing and start a local DNS server (there's a server in the github.com/miekg/dns package), but that would be some more code including selecting a random free port and using that in the tests.

huangapple
  • 本文由 发表于 2017年6月30日 17:21:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/44842960.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定