2012-09-04 8 views
5

Tôi có một dòng trong thử nghiệm của tôi:Minitest đặc tả tùy chỉnh khớp

page.has_reply?("my reply").must_equal true 

và để làm cho nó dễ đọc hơn tôi muốn sử dụng một khớp tùy chỉnh:

page.must_have_reply "my reply" 

Dựa trên các tài liệu cho https://github.com/zenspider/minitest-matchers tôi hy vọng tôi cần phải viết một đối sánh trông giống như sau:

def have_reply(text) 
    subject.has_css?('.comment_body', :text => text) 
end 
MiniTest::Unit::TestCase.register_matcher :have_reply, :have_reply 

Vấn đề là tôi không thể thấy cách để tham khảo chủ đề (tức là đối tượng trang). Các tài liệu nói "Chủ đề ghi chú phải là đối số đầu tiên trong xác nhận" nhưng điều đó không thực sự hữu ích.

Trả lời

6

Có một ví dụ nhỏ, bạn có thể tạo lớp học sẽ phản hồi tập hợp các phương thức matches?, failure_message_for_should, failure_message_for_should_not. Trong phương thức matches?, bạn có thể lấy tham chiếu đến chủ đề.

class MyMatcher 
    def initialize(text) 
    @text = text 
    end 

    def matches? subject 
    subject =~ /^#{@text}.*/ 
    end 

    def failure_message_for_should 
    "expected to start with #{@text}" 
    end 

    def failure_message_for_should_not 
    "expected not to start with #{@text}" 
    end 
end 

def start_with(text) 
    MyMatcher.new(text) 
end 
MiniTest::Unit::TestCase.register_matcher :start_with, :start_with 

describe 'something' do 
    it 'must start with...' do 
    page = 'my reply' 
    page.must_start_with 'my reply' 
    page.must_start_with 'my ' 
    end 
end 
1

Có nhiều cách để có được những gì bạn muốn ở đây. Cách đơn giản nhất là không gây rối với các khẳng định, kỳ vọng, hoặc đối sánh ở tất cả và chỉ sử dụng một khẳng định. Vì vậy, giả sử bạn đã có phương pháp has_reply? xác định, bạn chỉ có thể sử dụng này:

assert page.has_reply?("my reply") 

Nhưng, điều đó không giúp bạn có được must_have_reply cú pháp bạn đang yêu cầu. Và tôi nghi ngờ bạn thực sự có một phương pháp has_reply?. Vì vậy, chúng ta hãy bắt đầu.

Yêu cầu "cách nhận tham chiếu đến chủ đề (ví dụ: đối tượng trang)". Trong trường hợp này, đối tượng là đối tượng mà phương thức must_have_reply được xác định. Vì vậy, bạn nên sử dụng this thay vì subject. Nhưng nó không đơn giản như tất cả. Đối sánh thêm mức độ vô hướng mà chúng tôi không có với các xác nhận thông thường (assert_equal, refute_equal) hoặc kỳ vọng (must_be_equal, wont_be_equal). Nếu bạn muốn viết một Matcher, bạn cần triển khai API Matcher.

May mắn thay cho bạn, bạn không thực sự phải triển khai API. Vì có vẻ như bạn đang có ý định dựa vào bộ so khớp have_css của Cabybara, chúng ta có thể sử dụng lớp HaveSelector của Capybara và để nó triển khai đúng API. Chúng ta chỉ cần tạo mô-đun Matchers của riêng mình với một phương thức trả về một đối tượng HaveSelector.

# Require Minitest Matchers to make this all work 
require "minitest/matchers" 
# Require Capybara's matchers so you can use them 
require "capybara/rspec/matchers" 

# Create your own matchers module 
module YourApp 
    module Matchers 
    def have_reply text 
     # Return a properly configured HaveSelector instance 
     Capybara::RSpecMatchers::HaveSelector.new(:css, ".comment_body", :text => text) 
    end 

    # Register module using minitest-matcher syntax 
    def self.included base 
     instance_methods.each do |name| 
     base.register_matcher name, name 
     end 
    end 
    end 
end 

Sau đó, trong tập tin minitest_helper.rb của bạn, bạn có thể bao gồm các module quẹt để bạn có thể sử dụng nó. (Mã này sẽ bao gồm đối sánh trong tất cả các thử nghiệm.)

class MiniTest::Rails::ActiveSupport::TestCase 
    # Include your module in the test case 
    include YourApp::Matchers 
end 

Minitest Matchers làm tất cả việc nâng khó.Bạn có thể bây giờ bạn có thể sử dụng khớp của bạn như là một sự khẳng định:

def test_using_an_assertion 
    visit root_path 
    assert_have_reply page, "my reply" 
end 

Hoặc, bạn có thể sử dụng khớp của bạn như là một kỳ vọng:

it "is an expectation" do 
    visit root_path 
    page.must_have_reply "my reply" 
end 

Và cuối cùng bạn có thể sử dụng nó với một chủ đề:

describe "with a subject" do 
    before { visit root_path } 
    subject { page } 

    it { must have_reply("my reply") } 
    must { have_reply "my reply" } 
end 

Quan trọng: Để làm việc này, bạn phải sử dụng 'gem minitest-matchers', '> = 1.2.0' vì register_matcher không được định nghĩa trong các phiên bản trước đó của địa lý đó m.