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
****************************************
精彩评论