Rspec测试从对象构造函数生成方法对象

时间:2014-08-14 15:22:49

标签: ruby rspec yield

我有以下代码:

def initialize
  yield method(:fulfill), method(:reject) if block_given?
end

我无法测试是否会产生实际值method(:fulfill)method(:reject),因为在产生值时我无法访问该对象。

因此我想测试它:

expect do |b|
  PurePromise.new(&b)
end.to yield_with_args(PurePromise.instance_method(:fulfill), PurePromise.instance_method(:reject))

但是,UnboundMethod不等于Method,即使它引用相同的方法。

在匹配unbind的参数之前调用yield_with_args有没有办法转换屈服值?

2 个答案:

答案 0 :(得分:1)

我想到了一种方法,但它涉及调用私有方法,所以感觉有点hacky

subject = PurePromise.allocate
expect do |b|
  subject.send(:initialize, &b)
end.to yield_with_args(subject.method(:fulfill), subject.method(:reject))

任何更好的解决方案都将受到赞赏。

答案 1 :(得分:0)

我找到了一种使用rspec 3' s composable matchers的方法。

RSpec::Matchers.define :be_a_bound_method_of do |unbound_method|
  match do |bound_method|
    bound_method.unbind == unbound_method
  end
end

RSpec::Matchers.alias_matcher :a_bound_method_of, :be_a_bound_method_of

expect do |b|
  PurePromise.new(&b)
end.to yield_with_args(
           a_bound_method_of(PurePromise.instance_method(:fulfill)),
           a_bound_method_of(PurePromise.instance_method(:reject))
       )