使用RSpec测试哈希内容

70

我有一个测试,如下所示:

it "should not indicate backwards jumps if the checker position is not a king" do
    board = Board.new
    game_board = board.create_test_board
    board.add_checker(game_board, :red, 3, 3)
    x_coord = 3
    y_coord = 3
    jump_locations = {}
    jump_locations["upper_left"]  = true 
    jump_locations["upper_right"] = false 
    jump_locations["lower_left"]  = false
    jump_locations["lower_right"] = true
    adjusted_jump_locations = @bs.adjust_jump_locations_if_not_king(game_board, x_coord, y_coord, jump_locations)
    adjusted_jump_locations["upper_left"].should == true 
    adjusted_jump_locations["upper_right"].should == false 
    adjusted_jump_locations["lower_left"].should == false
    adjusted_jump_locations["lower_right"].should == false
  end 

我知道这段话很冗长。有没有更简洁明了地表达我的期望的方法?我查看了文档,但是找不到压缩期望的地方。谢谢。

4个回答

118

对于哈希表也同样适用:

expect(jump_locations).to include(
  "upper_left"  => true,
  "upper_right" => false,
  "lower_left"  => false,
  "lower_right" => true
)

来源: include 匹配器 @ relishapp.com


17
谢谢,David。顺便说一下,我是你的超级粉丝。非常喜欢《RSpec 书》。 - steve_gallagher
4
我希望有一个像match_array一样对应的方法。 - max pleaner
同意Fanage David的观点!你的《The Rspec Book》已经被翻阅得很熟了! - Dave Collins

38

仅想增加一点 @David 的回答。您可以在您的 include 哈希中嵌套和使用匹配器。例如:

# Pass
expect({
  "num" => 5, 
  "a" => { 
    "b" => [3, 4, 5] 
  }
}).to include({
  "num" => a_value_between(3, 10), 
  "a" => {
    "b" => be_an(Array)
  }
})

一个警告:一个嵌套的 include 哈希表必须测试所有的键,否则测试将失败,例如:
# Fail
expect({
  "a" => { 
    "b" => 1,
    "c" => 2
  }
}).to include({
  "a" => {
    "b" => 1
  }
})

8
你可以通过使用嵌套的包含来解决你的警告: "a" => { "b" => 1, "c" => 2 } }).to include({ "a" => include({ "b" => 1 }) })``` - AngelCabo
2
大多数匹配器都有“动词”和更长的“名词”别名,后者在嵌套时可能读起来更好:expect({“a”=> {“b”=> 1,“c”=> 2}})。to include({“a”=> a_hash_including({“b”=> 1})})。http://timjwade.com/2016/08/01/testing-json-apis-with-rspec-composable-matchers.html是一篇很好的博客文章。 - Beni Cherniavsky-Paskin
1
@AngelCabo,你的评论应该被接受为答案。在许多情况下都很有帮助。 - manpreet singh

6

RSpec 3的语法已经发生了改变,但include匹配器仍然是其中之一:

expect(jump_locations).to include(
  "upper_left" => true,
  "upper_right" => false,
  "lower_left" => false,
  "lower_right" => true
)

请参见内置匹配器#include-matcher


5
另一种测试整个内容是否为哈希的简单方法是检查内容是否为哈希对象本身:
it 'is to be a Hash Object' do
    workbook = {name: 'A', address: 'La'}
    expect(workbook.is_a?(Hash)).to be_truthy
end

对于上述问题,我们可以按照以下步骤进行检查:
expect(adjusted_jump_locations).to match(hash_including('upper_left' => true))

问题是关于测试哈希内容,而不是响应是否为哈希。 - ToTenMilan
1
@ToTenMilan,这就是为什么我强调它的原因。有“另一种方法……”可能会/可能不会有帮助。这取决于情况。 - Kiry Meas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接