开发者

How to mock an TCP connecting in Cucumber

I want to test one pr开发者_如何学运维ogram which can capture and send IP packets to some clients, so how to mock request or client in Cucumber? thanks


Normally I would answer the question with the cavet that it's a bad idea but this is such a bad idea I'm only going to answer half of it, how to mock in Cucumber generically.

You see Cucumber is meant to be a total test from the outside in so it's meant to completely run your code without any test doubles. The whole point is you are not unit testing but are testing your whole application.

"We recommend you exercise your whole stack when using Cucumber. [However] you can set up mocks with expectations in your Step Definitions." - Aslak Hellesøy, Creator of Cucumber

Granted you can do this but you are going to need to write your own the TCPServer and TCPSocket classes to avoid using the network and that can actually introduce bugs since your writing specs against your mock Net classes not the actual Net classes. Again, not a good idea.

Enough yapping, here's how to use mocks in Cucumber. (I'm going to assume you have a basic understanding of Cucumber and Ruby so I will skip some steps like how to require your class files in Cucumber.)

Let's say you have the following classes:

class Bar
  def expensive_method
    "expensive method called"
  end
end

class Foo

  # Note that if we don't send a bar it will default to the standard Bar class
  # This is a standard pattern to allow test injection into your code.
  def initialize(bar=Bar.new)
    @bar = bar
    puts "Foo.bar: #{@bar.inspect}"
  end

  def do_something
    puts "Foo is doing something to bar"
    @bar.expensive_method
  end

end

You should have the Bar and Foo classes required in your features/support/env.rb file but to enable RSpec mocks you need to add the following line:

require 'cucumber/rspec/doubles'

Now create a feature file like this one:

Feature: Do something
  In order to get some value
  As a stake holder
  I want something done

Scenario: Do something
  Given I am using Foo
  When I do something
  Then I should have an outcome

And add the steps to your step definitions file:

Given /^I am using Foo$/ do
  # create a mock bar to avoid the expensive call
  bar = double('bar')
  bar.stub(:expensive_method).and_return('inexpensive mock method called')
  @foo = Foo.new(bar)
end

When /^I do something$/ do
  @outcome = @foo.do_something
  # Debug display of the outcome
  puts ""
  puts "*" * 40
  puts "\nMocked object call:"
  puts @outcome
  puts ""
  puts "*" * 40
end

Then /^I should have an outcome$/ do
  @outcome.should_not == nil
end

Now when you run your feature file you should see:

****************************************

Mocked object call:
inexpensive mock method called

****************************************
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜