2012-07-11 27 views
11

en mi directorio de soporte pepino Tengo el siguiente en vcr.rb:Rubí joya VCR continúa registrando las mismas peticiones

require 'vcr' 

VCR.configure do |c| 
    c.cassette_library_dir = 'fixtures/vcr_cassettes' 
    c.hook_into :webmock 
    c.ignore_localhost = true 
    c.default_cassette_options = { record: :new_episodes } 
end 

estoy geocodificación nombres de ciudades que hace que las llamadas a la API de Google Maps. Estoy tratando de grabar y stub estas solicitudes, pero mantiene el registro de las mismas peticiones a un mismo archivo yml:

- request: 
    method: get 
    uri: http://maps.googleapis.com/maps/api/geocode/json?address=Miami,%20FL&language=en&sensor=false 
    body: 
     encoding: US-ASCII 
     string: '' 
    headers: 
     Accept-Encoding: 
     - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 
     Accept: 
     - ! '*/*' 
     User-Agent: 
     - Ruby 
    # response... 

- request: 
    method: get 
    uri: http://maps.googleapis.com/maps/api/geocode/json?address=Miami,%20FL&language=en&sensor=false 
    body: 
     encoding: US-ASCII 
     string: '' 
    headers: 
     Accept-Encoding: 
     - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 
     Accept: 
     - ! '*/*' 
     User-Agent: 
     - Ruby 

Es el mismo URL y muy misma petición, no debería VCR talón de la solicitud? ¿Cómo puedo evitar que mis especificaciones penetren en la API cada vez que trato de buscar la misma ciudad?

Respuesta

21

Es difícil saber con certeza qué está pasando con lo que ha publicado, pero puedo explicarle un poco más sobre cómo funciona la videograbadora y hacer algunas conjeturas sobre las posibles razones para esto comportamiento.

VCR usa request matchers para tratar de encontrar una interacción HTTP previamente grabada para reproducir. Durante una única sesión de casete, cuando se reproduce una interacción HTTP, se considera "utilizada" y no se volverá a reproducir (a menos que utilice la opción allow_playback_repeats).

Así que ... aquí hay un par de posibilidades que vienen a la mente:

  • Tal VCR no es capaz de satisfacer sus peticiones HTTP. ¿Qué solicitud de emparejamiento estás usando? Hay algunas formas fáciles de solucionar esto (ver a continuación).
  • Si no está usando :allow_playback_repeats (que es el valor predeterminado y cómo le recomiendo que use la videograbadora), entonces el comportamiento que está viendo podría ocurrir si se realizan varias solicitudes duplicadas en la prueba, por ejemplo, tal vez el cassette solo tiene una solicitud de coincidencia, pero su prueba es de 2, que podría reproducir una y grabar una (ya que está usando :new_episodes).

Para solucionar esto, le recomiendo que utilice la opción de obtener debug_logger VCR para imprimir lo que está haciendo y cómo se está tratando de coincidir con cada solicitud. Eso debería darte una idea de lo que está pasando. También puede anular cualquiera de the built in request matchers y proporciona su propia lógica y/o establecer un punto de interrupción en el matcher:

VCR.configure do |c| 
    c.register_request_matcher :uri do |request_1, request_2| 
    debugger # so you can inspect the requests here 
    request_1.uri == request_2.uri 
    end 
end 

También es posible que se han topado con un error VCR, aunque la comparación de la URI (usando String#==) es tal una operación básica que me cuesta imaginar un error allí. Siéntase libre de abrir un problema github (con suerte con la salida del registrador de depuración y/o un ejemplo de código que desencadena esto) si no puede resolverlo.

En una nota lateral, le recomiendo que utilice el modo de registro :once (predeterminado) en lugar de :new_episodes.:once nunca registrará interacciones HTTP adicionales con un videocasete existente; solo permite grabar un cassette una vez. Si una solicitud no coincide, generará un error que lo alertará sobre el hecho de que no podría coincidir. :new_episodes, por otro lado, registrará cualquier solicitud para la que no pueda encontrar una coincidencia, que es el comportamiento que estás viendo.

+2

@Erik J - Si hay * alguien *, debe escuchar acerca de [VCR] (https://github.com/myronmarston/vcr/) es alguien llamado Myron;) – Gareth

+0

Gracias, Myron, esperaba que apareciera ;) Me acabo de dar cuenta de que mis encabezados de respuesta incluyen 'Vence: - Vie, 13 Jul 2012 18:31:50 GMT" que es 24 horas después de la fecha de solicitud. ¿VCR lo nota y trata de hacer una solicitud nuevamente? Si es así, ¿hay alguna forma de desactivarlo? –

+0

No, la videograbadora no usa esto en absoluto. Hay una opción [re_record_interval] (https://www.relishapp.com/myronmarston/vcr/v/2-2-3/docs/cassettes/automatic-re-recording), pero eso no mira ningún encabezado (solo usa el intervalo configurado) y no produciría las interacciones duplicadas que estás viendo; reemplazaría la antigua interacción HTTP en lugar de solo agregar una nueva. –

2

Experimenté un comportamiento similar, así que lo que hago es básicamente mantenerme configurado en :none. Si surge alguna solicitud nueva, utilizo :any, ejecuto la parte del conjunto de pruebas que realizó las solicitudes y lo configuro nuevamente en :none.

Parece que :new_episodes utiliza algunas heurísticas extrañas para determinar qué nuevas solicitudes son y qué solicitudes ya se han producido. En nuestro caso, marcó dos solicitudes diferentes para las pasarelas de pago como las mismas, lo que condujo a interminables horas de depuración, porque obtuvimos una respuesta RefundOk a un CaptureRequest y cosas por el estilo. Mejor no use :new_episodes ...

+0

En lugar de la ': all',': none' alternar lo mencionas, yo recomiendo usar el ': una vez 'modo de registro. Actúa como ': ninguno' cuando un videocasete ya ha sido grabado, o': todos' cuando se trata de un nuevo videocasete. –

+0

Las "heurísticas extrañas" a las que se refiere para ': new_episodes' son simplemente las coincidencias de solicitud configuradas. Funcionan igual para todos los modos de grabación. El efecto de ': new_episodes' es que registrará las solicitudes que no coinciden con las grabadas previamente; en cambio, ': once' y': none' generará un error cuando esto ocurra. –

8

Cuando tuve un problema similar, me fijo que al hacer el ajuste match_requests_on más específico:

VCR.configure do |c| 
    c.default_cassette_options = { 
     match_requests_on: [:uri, :body, :method] 
    } 
end 
Cuestiones relacionadas