- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我创建了一个规范来测试用户如何确认他的帐户。它在以下场景中测试用户:
虽然下面这段代码完全未经测试(全部在浏览器中编写),但我不明白为什么它不起作用。然而,这些是我的担忧:
同样,这段代码甚至从未见过 sublime text 的光芒,所以可能会有一些小问题:
更干燥但更难遵循:
describe 'user spec', js: true do
before { visit root_path }
let(:user){ FactoryGirl.build(:user) }
module Helpers
def deliveries
ActionMailer::Base.deliveries
end
def last_email
deliveries.last
end
def sent_emails_count
deliveries.count
end
def reset_action_mailer
deliveries = []
end
def reload_user(user_name)
User.find_by(user_name: user_name) # like to know how to write a method that could find by any attribute, not just username. E.g. `reload_user(email: 'thisismyemail@gotmail.com)`
end
def register_user(user)
click_link 'sign up today!'
fill_in 'user_user_name', with: user.user_name
fill_in 'user_email', with: user.email
fill_in 'user_password', with: user.password
fill_in 'user_password_confirmation', with: user.password_confirmation
click_button 'Register'
end
def sign_out(user) # I have a 'useless' user parameter in there to make code more self-documenting. E.g. sign_out(user_1), sign_out(user_2)
click_link 'sign out'
end
def sign_in(user)
click_link 'sign_in'
fill_in 'user_email', with: user.user_name
fill_in 'user_password', with: user.password
end
end
# shared examples
shared_examples_for 'a succeeded confirmation attempt' do |user|
describe 'the page' do
subject { page }
it_should_behave_like 'profile_page'
it{ should have_selector '.alert-success', text: "Thankyou for confirming! You're now a fully fledged user!" }
it{ should have_selector 'h4', text: 'confirmed' }
end
describe 'the instance' do
it_should_behave_like 'an confirmed instance', user
end
end
shared_examples_for 'a failed confirmation_attempt' do |user|
describe 'the page' do
subject { page }
it_should_behave_like 'profile_page'
it{ should have_selector '.alert-error', text: "Sorry, that key is wrong!" }
it{ should have_selector 'h4', text: 'unconfirmed' }
end
describe 'the instance' do
it_should_behave_like 'an unconfirmed instance', user
end
end
shared_examples_for 'an unconfirmed instance' do |user|
subject { reload_user(user.user_name) }
its(:confirmed_at){ should be_nil }
its(:state){ should eq 'unconfirmed' }
end
shared_examples_for 'a confirmed instance' do |user|
subject { reload_user(user.user_name) }
its(:confirmed_at){ should eq Time.now }
its(:state){ should eq 'confirmed' }
end
scenario 'user signs up' do
before do
register_user(user)
end
describe 'the page' do
subject { page }
it_should_behave_like 'profile_page' # shared example that tests content and title.
it{ should have_selector '.alert-success', text: "welcome to the site, #{user.user_name}! Please check your inbox for a confirmation email. You won't be able to do anything untill you confirm your account!" }
it{ should have_selector 'h4', text: user.email }
it{ should have_selector 'h4', text: user.user_name }
it{ should have_selector 'h4', text: 'unconfirmed' }
end
describe 'the instance' do
subject { User.last } #is this the best way to do this? I want to do `user.reload` but I can't reload user because the user is built in memory (doesn't go through ActiveRecord), and so doesn't have an id
its(:confirmation_key_created_at){ should eq Time.now }
its(:confirmation_key){ should be_base64 } # my own matcher. No, I'm not an autistic maths genius, just testing it's 64 characters long ;)
its(:state){ should eq 'unconfirmed' }
end
describe 'last email' do
subject { last_email }
# using email-spec matchers https://github.com/bmabey/email-spec
it { should have_subject "Hi #{user.user_name}, confirmation link enclosed!" }
it { should deliver_to user.email }
it { should have_body_text user.confirmation_key }
end
scenario 'then attempts confirmation by following the confirmation link in his email' do
before do
visit culminate_path(user.confirmation_key) # In order to closer emulate what the user would do, I would like to actually get the last email and use capybara to click the confirmation link, rather then emulating the click as I'm doing here. How could I do this?
end
it_should_behave_like 'a succeeded confirmation attempt'
end
scenario 'then attempts confirmation by following a made up link' do
let(:user_2) { FactoryGirl.build(:user) }
before do
sign_out(user)
register_user(user_2) # could use FactoryGirl.create but this is an integration test. I want to emulate real-world events as much as possible
sign_out(user_2)
sign_in(user)
visit culminate_path(SecureRandom.urlsafe_base64)
end
it_should_behave_like 'a failed confirmation_attempt'
end
scenario 'then attempts confirmation by following a confirmation link for a different user' do
let(:user_2) { FactoryGirl.build(:user) }
before do
sign_out(user)
register_user(user_2) # could use FactoryGirl.create but this is an integration test. I want to emulate real-world events as much as possible
sign_out(user_2)
sign_in(user)
visit culminate_path(user_2.confirmation_key)
end
it_should_behave_like 'a failed confirmation_attempt'
end
scenario 'then signs out and attempts confirmation by following the confirmation link in his email' do
let(:user_2) { FactoryGirl.build(:user) }
before do
sign_out(user)
visit culminate_path(user.confirmation_key)
end
describe 'the page' do
subject { page }
it_should_behave_like 'sign_in_page'
it{ should have_selector '.alert-error', text: "Sorry, you need to be signed in inorder to attempt confirmation!" }
end
describe 'the instance' do
it_should_behave_like 'a confirmed instance', user
end
scenario 'then signs in and visits link again' do
before do
sign_in(user)
visit culminate_path(user.confirmation_key)
end
it_should_behave_like 'a succeeded confirmation attempt'
end
end
end
end
更容易理解但不像 DRY:
describe 'user spec', js: true do
before { visit root_path }
let(:user){ FactoryGirl.build(:user) }
let(:user_2) { FactoryGirl.build(:user) }
# helper methods and shared examples hidden for brevity
scenario 'user signs up' do
before do
register_user(user)
end
describe 'the page' do
subject { page }
it_should_behave_like 'profile_page' # shared example that tests content and title.
it{ should have_selector '.alert-success', text: "welcome to the site, #{user.user_name}! Please check your inbox for a confirmation email. You won't be able to do anything untill you confirm your account!" }
it{ should have_selector 'h4', text: user.email }
it{ should have_selector 'h4', text: user.user_name }
it{ should have_selector 'h4', text: 'unconfirmed' }
end
describe 'the instance' do
subject { reload_user(user.user_name)} #is this the best way to do this? I want to do `user.reload` but I can't reload user because the user is built in memory (doesn't go through ActiveRecord), and so doesn't have an id
its(:confirmation_key_created_at){ should eq Time.now }
its(:confirmation_key){ should be_base64 } # my own matcher. No, I'm not an autistic maths genius, just testing it's 64 characters long ;)
its(:state){ should eq 'unconfirmed' }
end
describe 'last email' do
subject { last_email }
# using email-spec matchers https://github.com/bmabey/email-spec
it { should have_subject "Hi #{user.user_name}, confirmation link enclosed!" }
it { should deliver_to user.email }
it { should have_body_text user.confirmation_key }
end
end
scenario 'a user signs up and then attempts confirmation by submitting a made up confirmation key' do
before do
register_user(user)
visit culminate_path(SecureRandom.urlsafe_base64)
end
it_should_behave_like 'a failed confirmation_attempt'
end
scenario 'a user signs up and then attempts confirmation by following a confirmation link for a different user' do
before do
register_user(user_2)
sign_out(user_2)
register_user(user)
visit culminate_path(user_2.confirmation_key)
end
it_should_behave_like 'a failed confirmation_attempt'
end
scenario 'then signs in and visits link again' do
before do
sign_in(user)
visit culminate_path(user.confirmation_key)
end
it_should_behave_like 'a succeeded confirmation attempt'
end
scenario 'a user signs out and then attempts confirmation by following the confirmation link in his email' do
before do
register(user)
sign_out(user)
visit culminate_path(user.confirmation_key)
end
describe 'the page' do
subject { page }
it_should_behave_like 'sign_in_page'
it{ should have_selector '.alert-error', text: "Sorry, you need to be signed in inorder to attempt confirmation!" }
end
describe 'the instance' do
it_should_behave_like 'an unconfirmed instance', user
end
end
end
最佳答案
我认为您消除大部分重复是正确的。但是,我不会使用嵌套场景,因为它们需要读者在文件中跳来跳去。我也不会使用共享示例,因为它们模糊了控制流。
我会做这样的事情:
describe "user signup and confirmation" do
let(:user) { # whatever }
before do
register_user
visit root_path
end
scenario "user signs up" do
page_should_show_that_user_is_not_confirmed
user_should_not_be_confirmed
# Write assertions here to assert that confirmation email was sent
confirmation_url = confirmation_url_from_email
visit confirmation_url
page_should_show_that_user_is_confirmed
user_should_be_confirmed
end
scenario "user logs out before visiting confirmation URL" do
# no need to do the same assertions as we did in the previous scenario before the visit
confirmation_url = confirmation_url_from_email
sign_out user
visit confirmation_url
page_should_show_that_user_is_confirmed
user_should_be_confirmed
end
scenario "user attempts to sign up with an unknown confirmation key" do
visit culminate_path("some garbage")
page_should_show_that_user_is_not_confirmed
user_should_not_be_confirmed
end
scenario "user attempts to sign up with the wrong confirmation key" do
user2 = # whatever
visit culminate_path(user2.confirmation_key)
page_should_show_that_user_is_not_confirmed
user_should_not_be_confirmed
end
def page_should_show_that_user_is_not_confirmed
# Assertions
end
def page_should_show_that_user_is_confirmed
# Assertions
end
def user_should_not_be_confirmed
# Assertions
end
def user_should_be_confirmed
# Assertions
end
def confirmation_url_from_email
# Don't assert anything, just get the URL from the email
end
end
它总体上可读性比较好,我认为重复的内容刚好足以保持可读性。
关于ruby - DRY 与重复特征规范,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23297781/
我想知道如何考虑需要您做出某些选择才能看到最终结果的搜索系统。我说的是 select 表单,您可以在其中根据您的选择继续操作,然后您会看到结果。 下面描述了我正在谈论的一个随机示例。想象一下 Init
您好,我目前正在编写一些软件来管理我们的库存。我搜索了 2 个表 master_stock(保存每一个股票代码和描述)库存(保存库存代码、地点、数量...) 一切都很好,但这是我遇到的问题。 假设我的
我有 2 个表,我想合并其数据。id 是我的关键字段(增量且不同)。表1和表2字段说明例如:id - 名称 - 值 我想将表2的所有数据插入表1,它们有不同的数据,但在某些行中有相同的id。 所以当我
我正在努力解决汇编中的一个问题,我必须获取十六进制代码的第一个字节 (FF) 并将其复制到整个值中: 0x045893FF input 0xFFFFFFFF output 我所做的
我有 Eclipse Indigo 版本,我可以在其中运行 Java 和 C++ 项目。 但我只想使用另一个 Eclipse 来编写 C++ 项目。所以我将 eclipse(不是工作区)的源文件夹复制
This question already has answers here: What is a NullPointerException, and how do I fix it? (12个答案)
This question already has answers here: Numbering rows within groups in a data frame (8个答案) 5个月前关闭。
我知道用q记录到寄存器中,但我想知道是否可以设置一些东西来快速调用最后一个记录,就像一样。 回顾最后一个简短的编辑命令(有关 的讨论请参阅 here。)。 我知道@@,但它似乎只有在执行@z之后才起作
来自 Eclipse 并且一直习惯于复制行,发现 Xcode 没有这样的功能是很奇怪的。或者是吗? 我知道可以更改系统范围的键绑定(bind),但这不是我想要的。 最佳答案 要删除一行:Ctrl-A
假设我有一个包含元素的列表,例如[1,2,3,4,5,6,7,8]。我想创建长度为 N 的该元素的所有排列。 因此,对于N = 4,它将是[[1,1,1,1],[1,1,1,2],[1,1,2,1],
我有一个带有 JMenu 的 JFrame。当我在某些情况下添加包含图像的 JPanel 时,程序首次启动时菜单会重复。调整大小时重复的菜单消失。任何建议都非常感激。谢谢。代码如下: public c
我正在尝试查找目录中文件的重复项。 我对这个 block 有一个问题,它以文件地址作为参数: public void findFiles(ArrayList list){ HashMap hm
我知道这个问题已经发布并且已经给出了答案,但我的情况不同,因为我在单个方法上填充多个下拉列表,所以如果我点击此链接 After every postback dropdownlist items re
我正在尝试为我的日历应用程序实现重复模式。我希望它的工作方式与 Outlook 在您设置重复约会时的工作方式相同。 public async Task> ApplyReccurrencePeriod
我有一个利用 cookie 来支持准向导的应用程序(即,它是一组相互导航的页面,它们必须以特定顺序出现以进行注册)。 加载 Logon.aspx 页面时 - 默认页面 - 浏览器 cookie 看起来
我有 3 个输入,代码检查它们是否为空,如果为空,则将变量值添加到输入中。 所以我有 3 个具有值的变量: var input1text = "something here"; var input2t
根据数组的长度更改数组的每个元素的最佳方法是什么? 例如: User #1 input = "XYZVC" Expected Output = "BLABL" User #2 input = "XYZ
我在让 Algolia 正常工作时遇到了一些麻烦。我正在使用 NodeJS 并尝试在我的数据库和 Algolia 之间进行一些同步,但由于某种原因似乎随机弹出大量重复项。 如您所见,在某些情况下,会弹
遵循以下规则: expr: '(' expr ')' #exprExpr | expr ( AND expr )+ #exprAnd | expr ( OR expr )+ #exprO
我有一个布局,我想从左边进入并停留几秒钟,然后我希望它从右边离开。为此,我编写了以下代码: 这里我在布局中设置数据: private void loadDoctor(int doctorsInTheL
我是一名优秀的程序员,十分优秀!