RSpec-测试是否使用之前定义的块调用了块 [英] RSpec -- test if block called with block defined in before

查看:74
本文介绍了RSpec-测试是否使用之前定义的块调用了块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近被问及如何进行测试RSpec(如果调用了一个块),并且该问题的答案似乎在简单的情况下有效.问题在于,使用块进行的初始化更加复杂.然后,它在before中完成,并在上下文中由许多不同的测试重用,其中一个测试是否评估了该块.参见示例:

I recently asked how to test in RSpec if a block was called and the answers to that question seem to work in a simple case. The problem is when the initialization with the block is more complex. Then it is done in before and reused by a number of different tests in the context, among them the one testing if the block was evaluated. See the example:

context "the node definition using block of code" do
  before do
     @n=node do
        # this block should be called
     end
     # some more complex setup concerning @n
  end

  it "should call the block" do
     # how to test it?
  end

  # here a bunch of other tests using @n

end

在这种情况下,具有更改局部变量值的副作用的解决方案不起作用.从块中引发异常是没有用的,因为必须正确评估整个语句以供其他测试使用.

In this case the solution with side effect changing value of a local variable does not work. Raising an exception from the block is useless since the whole statement must be properly evaluated to be used by the other tests.

很明显,我可以单独进行测试,但是这似乎很令人讨厌,因为我必须复制粘贴初始化部分,并且因为被称为块"的测试固有地属于此上下文.

Obviously I could do the tests separately, but it seems to stink, since I must copy-paste the initialization part and since the was-the-block-called test inherently belongs to this very context.

如何测试在这种情况下是否对该区块进行了评估?

How to test if the block was evaluated in such a case?

下面@zetetic提出的问题解释.

Explanation for question asked by @zetetic below.

上下文是我正在实现一种DSL,其中 nodes 由其参数和代码块定义(可以在node范围内定义其他内容).由于由节点的块定义的事物可能是非常通用的,因此至少对于第一次尝试,我只需要确保对块进行了评估,并将考虑用户在此处提供的内容.现在什么都没关系.

The context is that I'm implementing a kind of DSL, with nodes defined by their parameters and blocks of code (that can define something else in the scope of node). Since the things defined by the node's block can be pretty generic, at least for the first attempt I just need to be sure the block is evaluated and that what a user provides there will be considered. For now does not matter what it is.

可能我现在应该重构测试,并且使用模拟使它们测试行为而不是实现.但是,为了进行一些混合和动态处理发送给对象的消息,这将有些棘手.现在,这种测试的接受在我脑海中有点模糊;-)

Probably I should refactor my tests now and using mocks make them test behaviors rather then implementation. However it will be a little bit tricky, for the sake of some mixins and dynamic handling of messages sent to objects. For now the cincept of such tests is a little bit fuzzy in my head ;-)

无论如何,您的回答和评论帮助我更好地理解了RSpec的工作原理,并解释了为什么我尝试做的事情看起来好像不适合RSpec.

Anyway your answers and comments helped me to better understand how RSpec works and explained why what I'm trying to do looks as if it did not fit to the RSpec.

推荐答案

尝试类似的方法(未经我试用):

Try something like this (untested by me):

context "the node definition using block of code" do
  let(:node){
    node = Node.new "arg1", "arg2", node_block
    # more complex stuff here
    node
  }
  context "checking the block is called" do
    let(:node_block) {
      double = double("node_block")
      double.should_receive("some kind of arg").and_return("something")
      # this will now cause a fail if it isn't called
      double
    }
    it "should call the block" do
      node.blah()
    end
  end

  let(:node_block) {
    # some real code
  }

  subject { node.blah() }
  it { should == 2 }
  # ...
end

这是一段非常不稳定的代码(您必须填补空白,因为您没有做太多工作,而且let显然也是lambda,这可能意味着您已经(使用它),并使用letdouble来检查它的调用,并避免使用before,这实际上是出于副作用 not 设置要在其中使用的变量规格.

So that's a very shaky piece of code (you'll have to fill in the gaps as you didn't give very much to go on, and let is obviously a lambda too, which could mean you've got to play around with it a bit) that uses let and a double to check it's called, and avoids using before, which is really for side effects not setting up variables for use in the specs.

@zetetic做出非常有见地的评论,表示您不在此处测试行为.我不反对使用rspec进行更多的单元测试样式的工作(准则被打破),但是您可能会问,如果不调用该代码块,则在使用实际代码块时以后的测试将如何通过?从某种意义上说,我什至不确定您是否需要检查该块是否被调用,但只有您知道.

@zetetic makes a very insightful comment that you're not testing behaviour here. I'm not against using rspec for doing more unit test style stuff (guidelines are made to be broken), but you might ask how later tests will pass when using a real block of code if that block isn't being called? In a way, I'm not even sure you need to check the block is called, but only you know.

这篇关于RSpec-测试是否使用之前定义的块调用了块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆