2017-03-07 29 views
0

按照rspec expect message docs,當我們使用如下代碼:Rspec的期望接收(...)與(TIME_RANGE)

expect(double).to receive(:message).with(argument) 

argument響應#===,Rspec的將呼籲任何argument.===在實際傳遞但是如果我想檢查一段時間是否真的被傳入了,我該怎麼辦?

例如,我想測試,這種方法將正確的信息以正確的參數(它簡化):

def in_date_range(range) 
    activities.by_created_at(range) 
end 

像一個測試:

it 'passes correct arguments' do 
    range = Time.new(0)..(Time.new(0) + 1.hour) 

    expect(activities).to receive(:by_created_at).with(range) 

    in_date_range(range) 
end 

這種失敗,TypeError: can't iterate from Time

我懷疑這是因爲哪個rspec試圖在我的時間範圍內撥打#===並遇到麻煩。

有沒有辦法檢查我的時間範圍實際上是我通過的範圍?

我實際上並不是在尋找重疊的時間,而是範圍是相同的:它們具有相同的開始點和結束點。

我想我們可以做到這一點的一種方式是編寫自定義匹配器,但它似乎是一個不尋常的路線。

EDIT

另一種可能的解決方案是將方法分成兩個部分:

def compute_range(time_in) 
    (computations) 
    time1..time2 
end 

def in_date_range(time_in) 
    range = compute_range(time_in) 
    activities.by_created_at(range) 
end 

然後我可以測試,它返回適當的範圍內計算方法,並且對於較大的方法予可以在正確的輸入中進行測試,並將取得的結果從較小的方法的輸出轉換爲另一種方法,避開消息中檢查範圍的混淆。

這並沒有完全回答這個問題 - 你如何使用rspec receive(:message)檢查'接收特定範圍',但現在對我來說已經足夠了。

回答

0

編輯:

我有一點更多的時間來看看這個,我認爲錯誤在於某處activities.by_created_at(range)內。這必須試圖調用範圍內的循環。

下面是通過規格。我一直反對它創建一個虛擬Thing類和運行測試,一切都經過:

class Thing 
    def initialize(name) 
    @name = name 
    end 

    def in_date_range(range) 
    activities.by_created_at(range) 
    end 
end 

describe Thing do 
    specify 'Thing test' do 
    name = 'Tim' 
    expect(Thing).to receive(:new).with(name) 

    Thing.new(name) 
    end 

    specify 'Time test' do 
    range = Time.new(0)..(Time.new(0) + 1.hour) 
    t = Thing.new('Jimmy') 

    expect(t).to receive(:in_date_range).with(range) 

    t.in_date_range(range) 
    end 
end 

~/test (master) 
18:22:21$ rspec spec/models/thing_spec.rb 
Loading Enhanced Logger. 
Run options: include {:focus=>true} 
.. 

Finished in 0.14094 seconds (files took 2.89 seconds to load) 
2 examples, 0 failures 

編輯完

的問題是不是RSpec的檢查範圍。

我跑這和它的工作:

describe Thing do 
    specify 'Thing test', :focus do 
    range = 1..4 
    expect(Thing).to receive(:new).with(range) 

    Thing.new(1..4) 
    end 
end 


Run options: include {:focus=>true} 
. 

Finished in 0.09132 seconds (files took 2.59 seconds to load) 
1 example, 0 failures 

問題是與製作時間迭代。

看到這個問題:Iterate over Ruby Time object with delta

接受的答案的第二部分應該幫助你。

+0

哦有趣的完全發生

A發生!我不知道爲什麼我沒有檢查。這流露出一些光芒。編輯指定時間實例的問題,雖然我不明白時間迭代的相關性 –

0

makandracards

測試如果兩個日期範圍在Ruby或Rails的重疊

甲檢查,如果兩個日期或時間範圍A和B的重疊需要覆蓋很多情況下:

A部分重疊B A圍繞B B圍繞A A完全發生在B B之後完全發生在A 一個技巧涵蓋所有這些c單個表達式的檢查是查看每個範圍的開始日期是否在同一方向上查看另一個範圍的結束日期。

下面的代碼顯示瞭如何在Ruby on Rails中實現此功能。該示例是一個類Interval,它具有兩個屬性#start_date和#end_date。這些日期被認爲是包容性的,這意味着如果一個間隔在另一個間隔開始的那天結束,我們認爲這兩個間隔重疊。

注意我們如何爲加載的Ruby對象(Interval#overlappings?)和返回所有重疊間隔(Interval.overlapping)的作用域實現了一個版本。根據你的問題,你可能需要一個或兩個或那些。

class Interval < ActiveRecord::Base 

    validates_presence_of :start_date, :end_date 

    # Check if a given interval overlaps this interval  
    def overlaps?(other) 
    (start_date - other.end_date) * (other.start_date - end_date) >= 0 
    end 

    # Return a scope for all interval overlapping the given interval, including the given interval itself 
    named_scope :overlapping, lambda { |interval| { 
    :conditions => ["id <> ? AND (TIMEDIFF(start_date, ?) * TIMEDIFF(?, end_date)) >= 0", interval.id, interval.end_date, interval.start_date] 
    }} 

end 

算法

你能想象的算法是這樣的解釋:「如果兩個範圍的開端看其他範圍的結束,難道他們都在同一個方向看? 「

如果您在一張紙上畫,你可以看到,這種說法是對其中兩個範圍重疊的所有情況下都是這樣:

一個部分重疊乙 包圍着乙 乙圍繞 你也可以看到,該聲明是虛假的,其中範圍不重疊:乙 後完全B之後一個

+0

啊,不幸的是,我不清楚我的問題。我不是在尋找一個時間在某個時間範圍內的測試,而是一個範圍等於另一個範圍。 –

+0

如果你看,這就是這樣。它比較兩組開始和兩組結束。 – OneNeptune

+0

當我說'平等'我的意思是'開始時間是一樣的,結束時間是一樣的'。你的函數檢查重疊,除非我完全誤解了它。 我很欣賞那種優雅的數學。這是一個乾淨的解決方案,不幸的是,這不是我的問題。 –