2013-03-19 109 views
0

我是新来的Ruby/Rails和做turorial我想知道我怎么能解决我的小问题...实用红宝石轨道创造have_list_of_links为RSpec的测试

我有一个形容“用有效的信息”测试用户使用有效信息登录时应该发生什么或不应该发生什么。 在此过程中,我希望能够验证新页面上是否存在某些链接。在政党成员,只有2个环节,所以我们那样做:

it { should have_link('Profile', href: user_path(user)) } 
it { should have_link('Sign out', href: signout_path) } 

但是如果我们假设10个链接?我认为让一个帮手不会更容易?但我无法弄清楚如何编写它。这是我跟...来

然后在$ PROJECT /规格/支持/ utilities.rb文件,我定义了新的* have_list_of_links *功能:

RSpec::Matchers.define :have_list_of_links do |lol| 
    match do |page| 
    lol.each_pair do |label, link| 
       page.should have_link(label, href: link) 
    end 
    end 
end 

我知道这是不正确的做法,但我不知道该怎么做...

谢谢。

+0

你是什么意思**我知道这是不应该做的方式**通过看它应该工作,做你所期望的代码。你有任何错误?我可以看到的唯一副作用是所有链接都将在单个示例中运行,并且可能不适用于文档。 – Kocur4d 2013-03-20 02:52:50

+0

其实我不知道这是否是做了正确的方式,这更是我想说的... – jon 2013-03-20 08:56:11

+0

我有一个错误信息,我只好等到工作日复制的结束/粘贴这里。如果我明白你提到的副作用,我不确定。你会不会推荐这种实施测试的方式?但无论如何,最终我的目标只是练习一些不在tuto中编写的代码。 – jon 2013-03-20 09:03:05

回答

1

我在这里可以看到两个小问题。首先使用let语法在rspec中定义memoized变量。其次,当你建立你的散列时,请在括号里面加上* _path助手。

所以insted的:

lol = Hash[ 'Profile' => 'user_path(user)', 
      'Sign out' => 'signin_path'] 

有:

let(:lol) { Hash[ 'Profile' => user_path(user), 
        'Sign out' => signin_path] } 

你的描述块可能是:

describe "with valid information" do 
    let(:lol) { Hash[ 'Profile' => user_path(user), 
        'Sign out' => signin_path] } 

    it { should have_list_of_links(lol) } 
end 

由于副作用,我会告诉你的小例子。鉴于您在$ PROJECT/spec/support/utilities.rb文件中定义了匹配器,应用程序路由等设置正确,并且您在视图中有链接。

describe "Users pages" do 
    before { visit root_path } 
    let(:values) { Hash['Index' => users_path, 
         'Sign out' => signout_path, 
         'Sign in' => signin_path] } 

    subject { page } 

    describe "with valid informations" do 
    it { should have_list_of_links(values) } 
    end 
end 

运行rspec的:

> rspec 
. 

Finished in 0.00267 seconds 
1 example, 0 failures 

Randomized with seed 67346 

运行rspec的-f文件

>rspec -f documentation 
Users pages 
    with valid informations 
    should have link "Sign in" 

Finished in 0.00049 seconds 
1 example, 0 failures 

Randomized with seed 53331 

这是不明确的和误导性的,特别是文件交换。在新应用程序中运行rspec -f文档的一种常见做法您只需将手放在其上(如果它们使用rspec ofc)。为了更好地理解发生了什么。

如果不是有:

describe "Users pages" do 
    before { visit root_path } 

    subject { page } 

    describe "with valid informations" do 
    it { should have_link('Index', href: users_path) } 
    it { should have_link('Sign out', href: signout_path) } 
    it { should have_link('Sign in', href: signout_path) } 
    end 
end 

运行rspec的:

>rspec 
... 

Finished in 0.0097 seconds 
3 examples, 0 failures 

Randomized with seed 53347 

运行rspec的-f文件

>rspec -f documentation 
Users pages 
    with valid informations 
    should have link "Index" 
    should have link "Sign out" 
    should have link "Sign in" 

Finished in 0.00542 seconds 
3 examples, 0 failures 

Randomized with seed 40120 

我个人比较喜欢第二种情况(更详细的一个)。随着测试数量的增长以及测试结构变得越来越复杂,其价值越来越高。您可以简单地运行rspec -f文档以了解如何使用应用程序,而无需使用用户手册/教程。

+0

超级,感谢您的速成班!我会在今天晚上测试你的解决方案并分享结果。 还有一个问题:RSpec和行为驱动的编程是真的在网络公司中使用还是更理想的方式来做到这一点? – jon 2013-03-20 13:49:39

+0

好公司测试,坏公司不测试。他们正在测试什么(RSpec/Minitest /其他框架)只是个人的品味。如果我想说** Rspec和BDD **是“最好的”,你应该在** UnitTest和TDD上使用它**一半的人读这个问题会把我钉死,另外一半会给我买一杯饮料:) Bottom线是 - 对你测试的东西没有丝毫影响。只是测试:)。 – Kocur4d 2013-03-20 14:14:00

+0

好的,再次感谢信息,我的东西现在正在工作。我还发现一个非常类似职位 http://stackoverflow.com/questions/11916962/how-to-keep-rspec-tests-dry-with-lots-of-have-link?rq=1 稍微暴露视图不同。我想我需要继续尝试一些“实验”,我一定会回到这里。 ciao – jon 2013-03-20 22:06:41