RSpec:匹配receive_message_chain

时间:2016-07-12 16:32:33

标签: ruby-on-rails rspec

我试图存根:

Thing.where(uuid: options['uuid']).first

经:

allow(Thing).to receive_message_chain(:where, :first)
  .with(uuid: thing_double.uuid)
  .and_return(nil)

但这又回来了:

 #<Double (anonymous)> received :first with unexpected arguments
         expected: ({:uuid=>123})
              got: (no args)

我应该以不同的方式验证消息链的参数吗?

3 个答案:

答案 0 :(得分:5)

当参数与最终方法不同时,您可以将<?php class MY_Router extends CI_Router { protected function _set_routing() { if (file_exists(APPPATH.'config/routes.php')) { include(APPPATH.'config/routes.php'); } if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/routes.php')) { include(APPPATH.'config/'.ENVIRONMENT.'/routes.php'); } // Validate & get reserved routes if (isset($route) && is_array($route)) { isset($route['default_controller']) && $this->default_controller = $route['default_controller']; isset($route['translate_uri_dashes']) && $this->translate_uri_dashes = $route['translate_uri_dashes']; unset($route['default_controller'], $route['translate_uri_dashes']); $this->routes = $route; } if ($this->enable_query_strings) { if ( ! isset($this->directory)) { $route = isset($_GET['route']) ? trim($_GET['route'], " \t\n\r\0\x0B/") : ''; if ($route !== '') { $part = explode('/', $route); $this->uri->filter_uri($part[0]); $this->set_directory($part[0]); if ( ! empty($part[1])) { $this->uri->filter_uri($part[1]); $this->set_class($part[1]); // Testing function atm if ( ! empty($_GET['function'])) { $this->uri->filter_uri($_GET['function']); $this->set_method($_GET['function']); } $this->uri->rsegments = array( 1 => $this->class, 2 => $this->method ); } } else { $this->_set_default_controller(); } } // Routing rules don't apply to query strings and we don't need to detect // directories, so we're done here return; } // Is there anything to parse? if ($this->uri->uri_string !== '') { $this->_parse_routes(); } else { $this->_set_default_controller(); } } } with结合使用。因此消息:

receive_message_chain

这是有道理的 - RSpec如何知道链中的哪个方法应该接收参数?

要验证参数预期,请不要对链进行存根,只需存根#<Double (anonymous)> received :first with unexpected arguments

where

或省略参数:

allow(Thing).to receive(:where).with(uuid: 1).and_return([])
expect(Thing.where(uuid: 1).first).to eq nil
不建议IMO {p> allow(Thing).to receive_message_chain(:where, :first).and_return(nil) expect(Thing.where(uuid: 1).first).to eq nil 。来自文档:

  

你应该考虑使用receive_message_chain代码嗅觉

答案 1 :(得分:1)

这是我们解决类似情况的方法:

expect(Theme).to receive(:scoped).and_return(double('scope').tap do |scope| 
  expect(scope).to receive(:includes).with(:categories).and_return scope
  expect(scope).to receive(:where).with(categories: { parent_id: '1'}).and_return scope
  expect(scope).to receive(:order).with('themes.updated_at DESC').and_return scope
  expect(scope).to receive(:offset).with(10).and_return scope
  expect(scope).to receive(:limit).with(10000)
end)

答案 2 :(得分:0)

有时有时容易出错(我会间歇性地收到一条错误消息,指出“参数数量错误(0表示1+)”;尽管这似乎仅在单个测试中执行多个receive_message_chains时才会发生),但是您也可以选择这样链接“ with”方法:

fun flatten [] = ...
  | flatten ((x,y)::pairs) = ...

val evenNumbers pairs = ...