【发布时间】:2011-01-03 08:18:26
【问题描述】:
我想测试一个可以捕获IP数据包并将其发送给某些客户端的程序,那么如何在Cucumber中模拟请求或客户端?谢谢
【问题讨论】:
我想测试一个可以捕获IP数据包并将其发送给某些客户端的程序,那么如何在Cucumber中模拟请求或客户端?谢谢
【问题讨论】:
通常我会回答这个问题,但要注意这是一个坏主意,但这是个坏主意,我只回答一半,如何在 Cucumber 中进行一般模拟。
您会看到 Cucumber 旨在从外部进行全面测试,因此它意味着无需任何测试替身即可完全运行您的代码。重点是您不是在进行单元测试,而是在测试整个应用程序。
“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,黄瓜的创造者
您可以做到这一点,但您将需要编写自己的 TCPServer 和 TCPSocket 类以避免使用网络,并且实际上可能会引入错误,因为您针对模拟 Net 类编写规范不是实际的网络类。同样,这不是一个好主意。
够了,下面介绍如何在 Cucumber 中使用模拟。 (我假设你对 Cucumber 和 Ruby 有基本的了解,所以我会跳过一些步骤,比如如何在 Cucumber 中要求你的类文件。)
假设您有以下类:
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
features/support/env.rb 文件中应该有所需的 Bar 和 Foo 类,但要启用 RSpec 模拟,您需要添加以下行:
require 'cucumber/rspec/doubles'
现在创建一个类似这样的功能文件:
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
并将步骤添加到您的步骤定义文件中:
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
现在,当您运行功能文件时,您应该会看到:
****************************************
Mocked object call:
inexpensive mock method called
****************************************
【讨论】: