如何在Cucumber中模拟TCP连接

时间:2010-10-21 01:46:23

标签: ruby cucumber

我想测试一个可以捕获并发送IP数据包给某些客户端的程序,那么如何在Cucumber中模拟请求或客户端?感谢

1 个答案:

答案 0 :(得分:5)

通常情况下,我会回答这个问题,这是一个不好的主意,但这是一个糟糕的主意,我只会回答其中的一半,如何在黄瓜中一般地进行模拟。

你看到Cucumber是一个来自外部的全面测试,因此它意味着完全运行你的代码而不需要任何测试双打。重点是你不是单元测试,而是测试你的整个应用程序。

We recommend you exercise your whole stack when using Cucumber. [However] you can set up mocks with expectations in your Step Definitions.” - 黄瓜的创造者AslakHellesøy

当然可以执行此操作但是您需要编写自己的TCPServer和TCPSocket类以避免使用网络,并且实际上可能会引入错误,因为您的编写规范针对您的模拟Net类不是实际的Net类。再次,不是一个好主意。

足够的yapping,这里是如何在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

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