2010-04-15 11 views
6

Ist es möglich, meinen Controller abzudecken, der stark von Etags mit Komponententests abhängt?Wie testet man die ETag Zwischenspeicherung?

Hier ist, was ich versuche zu tun: für den Fall, wenn Seite nicht alt ist (was bedeutet, dass es frisch ist), ich bin einige Header zur Antwort hinzufügen.

Wenn ich versuche, alles (rspec) zu testen, egal wie viele ähnliche Anfragen ich habe, bekomme ich immer noch 200 OK statt 304, und meine Kopfzeile wird nicht geändert. Außerdem, wenn ich request.fresh (Antwort) nachverfolge, ist es IMMER falsch.

Allerdings funktioniert es perfekt im Browser. Ich habe bereits versucht, ActionController :: Base.perform_caching = true anzugeben, es ändert jedoch nicht die Gesamtsituation.

Danke

Antwort

4

Ok, hier ist ein Punkt:

Bevor die Anforderung schlägt, lesen Sie alles, was zu ETags in Rails-Code verwandt ist und nicht zu vergessen zu setzen:

request.env["HTTP_IF_MODIFIED_SINCE"] 
request.env["HTTP_IF_NONE_MATCH"] 

Da sie für ETag-Tests erforderlich sind.

+0

Hallo, könntest du im Detail erklären was das bedeutet? Wenn ich das request.env setze, enthält es immer noch nicht das Etag. – Tosa

+0

@Tosa siehe meine Antwort unten für einige Ideen (ich konnte nicht so viel Code in einem Kommentar posten). – szeryf

+0

Wie ist das eine Antwort, geschweige denn die akzeptierte Antwort? Sie sagen, machen Sie ein paar Nachforschungen und setzen Sie einige env-Variablen, aber Sie sagen nicht, was Sie recherchieren sollen und worauf Sie die env-Variablen setzen sollen. –

4

Rails-Hashes der: etag Sie bieten:

headers['ETag'] = %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(etag))}") 

so etwas Einstellung einfach wie

frash_when(:etag => 'foo') 

nur durch die rechte Digest ausgelöst werden würde (die doppelten Anführungszeichen sind notwendig)

def with_etag 
    if stale?(:etag => 'foo') 
    render :text => 'OK' 
    end 
end 

... tested by ... 

@request.env['HTTP_IF_NONE_MATCH'] = '"acbd18db4cc2f85cedef654fccc4a4d8"' 
get :with_etag 
assert_equal 304, @response.status.to_i 

gleich für modifiziert:

def with_modified 
    if stale?(:last_modified => 1.minute.ago) 
    render :text => 'OK' 
    end 
end 

... tested by ... 

@request.env['HTTP_IF_MODIFIED_SINCE'] = 2.minutes.ago.rfc2822 
get :with_modified 
assert_equal 304, @response.status.to_i 
+0

oh, das war eine Frage von Ewigkeiten her. ich denke, es ist immer noch rails 2.3.5, also haben sich die dinge seither sehr verändert. – 0100110010101

7

Hier ist, wie Sie können testen, ob zweite Anfrage 304 Antwort zurückgibt:

get action, params 
    assert_response 200, @response.body 
    etag = @response.headers["ETag"] 
    @request.env["HTTP_IF_NONE_MATCH"] = etag 
    get action, params 
    assert_response 304, @response.body 
0

Rails 4.2 jetzt nimmt auch in um den Digest der Vorlage zu berücksichtigen. Für mich hat folgendes geklappt:

def calculate_etag(record, template) 
    Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key([ 
    record, 
    controller.send(:lookup_and_digest_template, template) 
    ])).inspect 
end 

def set_cache_headers(modified_since: nil, record: nil, template: nil) 
    request.if_modified_since = modified_since.rfc2822 
    request.if_none_match = calculate_etag(record, template) 
end 

set_cache_headers(
    modified_since: 2.days.ago, 
    record: @book, 
    template: 'books/index' 
)