2012-03-13 36 views
5

Tôi đang đọc qua một số Rspec được viết bởi người đã rời công ty. Tôi đang tự hỏi về dòng này:Lợi ích của Class.new trong Rspec

let(:mailer_class) { Class.new(AxeMailer) } 
    let(:mailer) { mailer_class.new } 

    describe '#check' do 
    before do 
     mailer_class.username 'username' 
     mailer.from '[email protected]' 
     mailer.subject 'subject' 
    end 
    subject { lambda { mailer.send(:check) } } 

Nó được thử nghiệm lớp này:

class AxeMailer < AbstractController::Base 

    def self.controller_path 
    @controller_path ||= name.sub(/Mailer$/, '').underscore 
    end 

Tôi muốn biết sự khác biệt giữa điều này và let(:mailer_class) { AxeMailer }.

Tôi hỏi điều này bởi vì hiện tại khi tôi chạy thử nghiệm, nó sẽ khiếu nại name là không. Nhưng nếu tôi thay đổi nó, nó sẽ kiểm tra tốt.

Tôi nghĩ vấn đề này bắt đầu sau khi sử dụng Rails 3.2 và tôi nghĩ rằng name được kế thừa từ AbstractController :: Base.

Điều này giống nhau trong bảng điều khiển (có nghĩa là nó không phải là Rspec cụ thể), tôi có thể làm AxeMailer.name không có lỗi, nhưng nếu tôi làm Class.new(AxeMailer) thì có vấn đề.

Câu hỏi của tôi là:

  1. Có một lý do để sử dụng Class.new(AxeMailer) qua AxeMailer
  2. Có một vấn đề nếu tôi chỉ cần thay đổi này?
  3. Có cách nào không thay đổi thông số kỹ thuật và vượt qua thông số không?
+0

Bạn có thể đăng thêm mã kiểm tra ngoài phương thức 'let' không? Điều đó sẽ giúp chúng tôi xác định lý do tại sao nó được viết theo cách này. –

+0

chỉ cần thêm một số, điều đó có đủ không? – lulalala

+0

với tôi, không có lý do gì. – shingara

Trả lời

2

Tôi đoán nó được viết là vì dòng mailer_class.username 'username'. Nếu bạn chỉ sử dụng trực tiếp AxeMailer, cài đặt username sẽ được chuyển qua lại giữa các lần kiểm tra. Bằng cách tạo một lớp con mới cho mỗi bài kiểm tra, bạn có thể đảm bảo rằng không có trạng thái nào được chuyển giữa chúng.

+0

Tôi nghĩ rằng đây có lẽ là lý do (không phải là anyways quan trọng). Tôi đã sửa đổi nó thành: '@controller_path || = parent.name.sub (/ Mailer $ /, '') .underscore' và có vẻ như đã trôi qua ngay bây giờ – lulalala

0

Tôi không biết nếu mailer_class đang được sử dụng bên trong spec thực tế hay không, nhưng đây là những gì tôi nghĩ rằng thiết lập của bạn sẽ giống như thế:

let(:mailer) { AxeMailer.new } 

describe '#check' do 
    before do 
    AxeMailer.username 'username' 
    mailer.from '[email protected]' 
    mailer.subject 'subject' 
    end 
    subject { lambda { mailer.send(:check) } } 

Có chỉ dường như không được nhu cầu cho lớp ẩn danh đã được tạo ra. Ngoài ra, đây chỉ là ý kiến ​​của tôi, nhưng subject của bạn trông hơi lạ. Spec của bạn có lẽ nên quấn chủ đề trong một lambda nếu nó cần, nhưng không làm điều đó trong subject của bạn.

Về lỗi mà bạn đang nhìn thấy ban đầu, các lớp nặc danh không có tên:

1.9.3-p0 :001 > Class.new.name 
=> nil 

Một số phần của ActionMailer :: Base phải cố gắng sử dụng tên lớp cho một cái gì đó (đăng nhập có lẽ) và phá vỡ khi không phải.

+0

Cảm ơn. 'Name' được sử dụng trong phương thức' self.controller_path'. Nó ghi đè 'self.controller_path' của' AbstractController :: Base'.Vì nó đang làm mới một loại 'AbstractController :: Base' nên nó cũng hoạt động (và đã hoạt động trước đó). – lulalala