标签: rr

在测试"无限循环"时,最佳做法是什么?

我的基本逻辑是在某个地方运行无限循环并尽可能地测试它.拥有无限循环的原因并不重要(游戏的主循环,类似守护进程的逻辑......)而且我更多地询问有关这种情况的最佳实践.

我们以此代码为例:

module Blah
  extend self

  def run
     some_initializer_method
     loop do
        some_other_method
        yet_another_method
     end
  end
end
Run Code Online (Sandbox Code Playgroud)

我想Blah.run使用Rspec 测试方法(我也使用RR,但普通的rspec是一个可接受的答案).

我认为最好的方法是分解更多,比如将循环分成另一种方法或其他方法:

module Blah
  extend self

  def run
     some_initializer_method
     do_some_looping
  end

 def do_some_looping
   loop do
     some_other_method
     yet_another_method
   end
 end
end
Run Code Online (Sandbox Code Playgroud)

...这允许我们测试run和模拟循环...但是在某些时候需要测试循环内的代码.

那么在这种情况下你会怎么做?

根本就没有测试这个逻辑,这意味着测试some_other_method&yet_another_method但不do_some_looping

通过模拟在某个时刻让循环中断?

......别的什么?

ruby tdd rspec ruby-on-rails rr

24
推荐指数
3
解决办法
5938
查看次数

当对象的构造函数构建另一个对象时进行存根

所以我有一些代码,大致简化,看起来像这样:

class B
  def initialize opts
    @opts = opts
  end
end

class A
  def initialize opts
    # defaults etc applied to opts
    @b = B.new opts
  end
end
Run Code Online (Sandbox Code Playgroud)

换句话说,当我使用选项初始化A时,它会创建一个B并将一组修改过的选项传递给它.

我想测试B.new得到正确的论点.现在,我正在这样做,使用RSpec/RR:

@b = Object.new
# stub methods on @b here
stub(B).new { |options|
  options[:foo].should == 'whatever'
  @b
}
A.new({:foo => 'whatever'})
Run Code Online (Sandbox Code Playgroud)

但这有两个问题.

首先,我无法B使用实际选项实例化实际副本.如果我在块中调用B.new,它会调用存根版本并循环直到堆栈弹出.我可以@b = B.new在存根之前设置,但我不知道将要传递的选项,从而击败测试点.

(并且在有人打电话给我之前:是的,在严格的单元测试教条中,A的测试应该在B中删除任何方法,并且需要大量存根意味着你的代码首先是坏的.)

其次,should在测试设置中,而不是在it ... do ... end之后的单独块中,感觉是错误的.但由于我不能创造一个实际的B(见上文),我也无法真正询问它的建设后状态.

有任何想法吗?

ruby constructor rspec stubbing rr

5
推荐指数
2
解决办法
7228
查看次数

以编程方式访问 gdb 中观察点的旧值和新值

我真正在做的是尝试在设置或清除单个位时设置观察点。我通过在包含该位的字上设置一个观察点,然后使其成为条件*word & mask(用于设置或(~*word) & mask清除)来做到这一点。

问题是同一个字中的一些其他位可能会被修改,并且条件可能已经匹配。如果我有旧值和新值,我可以设置(($old ^ $new) & mask).

我查看了 pythongdb.Breakpoint类,但它似乎也没有收到此信息。

我想我可以发疯并设置一个命令列表,该列表在值*word更改时记录当前值,并将其用作$old. 但有一半时间我使用它,我实际上是通过 rr 使用它,所以我可能会倒退。

gdb rr

5
推荐指数
1
解决办法
380
查看次数

如何在Rails 3上使用RR(双红宝石)模拟一个带方法的方法

我正在使用Koala gem来发出facebook请求,我有以下代码:

  @graph = Koala::Facebook::API.new(oauth_token)
  @graph.batch do |batch_api|
    #... do stuff here
  end
Run Code Online (Sandbox Code Playgroud)

我想模拟批量调用来模拟我们在那里做的事情.

这是我在RR中所拥有的.

oauth_token= "Sometoken"
batch_api_mock = nil
graph_mock = mock(Koala::Facebook::API).new(oauth_token).mock!
graph_mock.batch.returns do
  yield batch_api_mock if block_given?
end
Run Code Online (Sandbox Code Playgroud)

问题是block_given?即使在我的源代码中传递了一个块,它也会返回false.

我如何使用RR模拟一个采用块的方法?

testing mocking rr ruby-on-rails-3

3
推荐指数
1
解决办法
1428
查看次数

更改数据库的Rspec操作

我对涉及影响DB的控制器方法的rpsec测试的行为有点困惑.我见过很多涉及POST和DELETE的rspec测试示例,人们检查是否创建或删除了对象.在大多数这些测试中,人们只需通过以下测试检查数据库中模型的计数是增加还是减少:

delete :clear_photos, :id => @album.id
@album.photos.size.should == 0 
Run Code Online (Sandbox Code Playgroud)

或与lambdas:

lambda {delete :destroy, :id => @photo.id}.should change(@album.photos, :size).by(-1)
Run Code Online (Sandbox Code Playgroud)

在最后一个例子中语法并不完美,但我的观点是,根据我的经验,我需要在对象上调用reload才能通过任何这些测试,但出于某种原因,其他人能够使它们工作没有显式调用重载.每次我测试db create/destroy动作时调用重载的东西对我来说都很可疑.

谁能帮我理解发生了什么?谢谢!

实际代码更新

it "should clear all photos for an album" do
  @album = Factory(:album, :photos => [Factory(:photo), Factory(:photo)])
  delete :clear, :album_id => @album.id
  @album.photo_count.should == 0
end
Run Code Online (Sandbox Code Playgroud)

我收到了这个回复:

'PhotosController#clear should clear all photos for an album' FAILED
expected: 0,
     got: 2 (using ==)
./spec/controllers/photos_controller_spec.rb:17:
Run Code Online (Sandbox Code Playgroud)

如果我在调用photo_count之前重新加载@album,它会起作用.

ruby rspec ruby-on-rails rr

2
推荐指数
1
解决办法
2181
查看次数