RSpec : 여러 변경 예상
기능 사양에서 양식을 제출할 때 모델의 많은 변경 사항을 확인하고 싶습니다. 예를 들어 사용자 이름이 X에서 Y로 변경되었고 암호화 된 암호가 임의의 값으로 변경되었는지 확인하고 싶습니다.
이미 그것에 대한 몇 가지 질문이 있다는 것을 알고 있지만 나에게 적합한 답을 찾지 못했습니다. 가장 정확한 대답은 ChangeMultiple여기에서 Michael Johnston 의 matcher 처럼 보입니다 . RSpec이 두 테이블에서 변경을 예상 할 수 있습니까? . 단점은 알려진 값에서 알려진 값으로의 명시적인 변경 사항 만 확인한다는 것입니다.
더 나은 일치자가 어떻게 보일 수 있다고 생각하는지에 대한 의사 코드를 만들었습니다.
expect {
click_button 'Save'
}.to change_multiple { @user.reload }.with_expectations(
name: {from: 'donald', to: 'gustav'},
updated_at: {by: 4},
great_field: {by_at_leaset: 23},
encrypted_password: true, # Must change
created_at: false, # Must not change
some_other_field: nil # Doesn't matter, but want to denote here that this field exists
)
또한 ChangeMultiple다음과 같이 matcher 의 기본 골격을 만들었습니다 .
module RSpec
module Matchers
def change_multiple(receiver=nil, message=nil, &block)
BuiltIn::ChangeMultiple.new(receiver, message, &block)
end
module BuiltIn
class ChangeMultiple < Change
def with_expectations(expectations)
# What to do here? How do I add the expectations passed as argument?
end
end
end
end
end
하지만 이제 이미이 오류가 발생합니다.
Failure/Error: expect {
You must pass an argument rather than a block to use the provided matcher (nil), or the matcher must implement `supports_block_expectations?`.
# ./spec/features/user/registration/edit_spec.rb:20:in `block (2 levels) in <top (required)>'
# /Users/josh/.rvm/gems/ruby-2.1.0@base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
# /Users/josh/.rvm/gems/ruby-2.1.0@base/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `block in load'
이 맞춤 매처를 만드는 데 도움을 주시면 감사하겠습니다.
RSpec 3에서는 한 번에 여러 조건을 설정할 수 있습니다 (따라서 단일 기대 규칙이 깨지지 않습니다). 다음과 같이 보일 것입니다.
expect {
click_button 'Save'
@user.reload
}.to change { @user.name }.from('donald').to('gustav')
.and change { @user.updated_at }.by(4)
.and change { @user.great_field }.by_at_least(23}
.and change { @user.encrypted_password }
그래도 완전한 해결책은 아닙니다. 내 연구가 진행되는 한 and_not아직 쉬운 방법이 없습니다 . 마지막 수표도 확실하지 않습니다 (중요하지 않은 경우 왜 테스트합니까?). 당연히 사용자 정의 매처 내에서 래핑 할 수 있어야합니다 .
여러 레코드가 변경되지 않았는지 테스트하려면을 사용하여 매처를 반전 할 수 있습니다 RSpec::Matchers.define_negated_matcher. 그래서 추가
RSpec::Matchers.define_negated_matcher :not_change, :change
파일의 맨 위에 (또는 rails_helper.rb) 다음을 사용하여 연결할 수 있습니다 and.
expect{described_class.reorder}.to not_change{ruleset.reload.position}.
and not_change{simple_ruleset.reload.position}
The accepted answer is not 100% correct since the full compound matcher support for change {} has been added in RSpec version 3.1.0. If you try to run the code given in accepted answer with the RSpec version 3.0, you would get an error.
In order to use compound matchers with change {}, there are two ways;
- First one is, you have to have at least RSpec version 3.1.0.
- Second one is, you have to add
def supports_block_expectations?; true; endinto theRSpec::Matchers::BuiltIn::Compoundclass, either by monkey patching it or directly editing the local copy of the gem. An important note: this way is not completely equivalent to the first one, theexpect {}block runs multiple times in this way!
The pull request which added the full support of compound matchers functionality can be found here.
BroiSatse's answer is the best, but if you are using RSpec 2 (or have more complex matchers like .should_not), this method also works:
lambda {
lambda {
lambda {
lambda {
click_button 'Save'
@user.reload
}.should change {@user.name}.from('donald').to('gustav')
}.should change {@user.updated_at}.by(4)
}.should change {@user.great_field}.by_at_least(23}
}.should change {@user.encrypted_password}
참고URL : https://stackoverflow.com/questions/29388777/rspec-expect-to-change-multiple
'Program Club' 카테고리의 다른 글
| 파일 이름의 배치 명령 날짜 및 시간 (0) | 2020.11.19 |
|---|---|
| Spring MVC의 뷰 기술로 JSF 사용 (0) | 2020.11.19 |
| webdesign-웹에 가장 적합한 jpg 또는 png (0) | 2020.11.19 |
| Mac 터미널 Vim은 줄 끝에서만 백 스페이스를 사용합니다. (0) | 2020.11.19 |
| 중앙 양식 제출 버튼 HTML / CSS (0) | 2020.11.19 |