简体   繁体   中英

Trouble mocking `Resolv::DNS.open`

I'm trying to mock the code below using MiniTest/Mocks. But I keep getting this error when running my test.

Minitest::Assertion: unexpected invocation: #<Mock:0x7fa76b53d5d0>.size()
unsatisfied expectations:
- expected exactly once, not yet invoked: #<Mock:0x7fa76b53d5d0>.getresources("_F5DC2A7B3840CF8DD20E021B6C4E5FE0.corwin.co", Resolv::DNS::Resource::IN::CNAME)
satisfied expectations:
- expected exactly once, invoked once: Resolv::DNS.open(any_parameters)

code being tested

txt = Resolv::DNS.open do |dns|
            records = dns.getresources(options[:cname_origin], Resolv::DNS::Resource::IN::CNAME)
          end
          binding.pry
          return (txt.size > 0) ? (options[:cname_destination].downcase == txt.last.name.to_s.downcase) : false

my test

::Resolv::DNS.expects(:open).returns(dns = mock)
  dns.expects(:getresources)
     .with(subject.cname_origin(true), Resolv::DNS::Resource::IN::CNAME)
     .returns([Resolv::DNS::Resource::IN::CNAME.new(subject.cname_destination)])
     .once

Right now you are testing that Resolv::DNS receives open returns your mock but since you seem to be trying to test that the dns mock is receiving messages you need to stub the method and provide it with the object to be yielded

Try this instead:

 dns = mock 
 dns.expects(:getresources)
   .with(subject.cname_origin(true), Resolv::DNS::Resource::IN::CNAME)
   .once
 ::Resolv::DNS.stub :open, [Resolv::DNS::Resource::IN::CNAME.new(subject.cname_destination)], dns do 
   # whatever code actually calls the "code being tested" 
 end 
 dns.verify

The second argument to stub is the stubbed return value and third argument to stub is what will be yielded to the block in place of the original yielded.

In RSpec the syntax is a bit simpler (and more semantic) such that:

 dns = double 
 allow(::Resolv::DNS).to receive(:open).and_yield(dns) 
 expect(:dns).to receive(:getresources).once
   .with(subject.cname_origin(true), Resolv::DNS::Resource::IN::CNAME)
   .and_return([Resolv::DNS::Resource::IN::CNAME.new(subject.cname_destination)])
  # whatever code actually calls the "code being tested" 

您可以使用 DnsMock 编写更具可读性的集成测试,而不是存根/模拟代码的一部分: https : //github.com/mocktools/ruby-dns-mock

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM