[RUBY] [RSpec] WebMock gère les expressions régulières et les chaînes de requête Array

introduction

WebMock est une bibliothèque fictive bien connue qui existe depuis longtemps, mais je vais résumer ce que j'ai essayé de diverses manières en essayant de faire une petite vérification détaillée avec RSpec comme mon propre mémo. Nous traitons principalement des méthodes de vérification des requêtes HTTP, en supposant des requêtes vers des API externes.

environnement

Ruby : 2.7.1 RSpec : 3.9.0 webmock : 3.8.3

Code à tester

À titre d'exemple, cette fois, je vais demander à https://jsonplaceholder.typicode.com/.

sample.ruby


require 'net/http'

class Sample
  def request(params = {})
    URI.parse('https://jsonplaceholder.typicode.com/todos')
      .tap { |uri| uri.query = URI.encode_www_form(params) }
      .then { |uri| Net::HTTP.get_response(uri) }
      .then { |res| res.body if res.is_a?(Net::HTTPSuccess) }
  end
end

Forme basique

Utilisez stub_request de webmock pour faire une demande à l'URL spécifiée une simulation. De plus, la vérification au moment de «attend» est effectuée par le modèle en utilisant «a_request».

sample_spec.rb


context 'Forme basique' do
  before do
    stub_request(:get, 'https://jsonplaceholder.typicode.com/todos').and_return(status: 200, body: 'hoge')
  end

  it 'Pour être demandé correctement' do
    expect(Sample.new.request).to eq 'hoge'
    expect(a_request(:get, 'https://jsonplaceholder.typicode.com/todos')).to have_been_made.once
  end
end

context 'Formulaire de base 2 Vérifier la chaîne de requête' do
  before do
    stub_request(:get, 'https://jsonplaceholder.typicode.com/todos?userId=2').and_return(status: 200, body: 'hoge')
  end

  it 'Pour être demandé correctement' do
    expect(Sample.new.request(userId: 2)).to eq 'hoge'
    expect(
      a_request(:get, 'https://jsonplaceholder.typicode.com/todos').with(query: { userId: 2 })
    ).to have_been_made.once
  end
end

--have_bee_made est un matcher pour RSpec fourni par WebMock. Il existe plusieurs autres matchers disponibles.

Je souhaite utiliser un élément de type joker avec une expression régulière

Par exemple, vous pouvez changer l'URL que vous demandez de todos à todos / 1, ou vous pouvez vouloir tester en spécifiant plus de chaînes de requête, mais dans ce cas, vous pouvez vouloir faire correspondre chaque demande. Si vous ne changez pas la chaîne URL de stub_request, elle ne sera pas moquée. C'est un problème, nous allons donc y remédier en utilisant des expressions régulières.

stub_request(:get, /https:\/\/jsonplaceholder.typicode.com/).and_return(status: 200, body: 'hoge')

En faisant cela, toutes les requêtes sous le domaine https: // jsonplaceholder.typicode.com / seront simulées et pourront être vérifiées avec ʻa_request`.

Les expressions régulières peuvent également être utilisées dans ʻa_request`.

expect(a_request(:get, /https:\/\/jsonplaceholder.typicode.com/)).to have_been_made

Cependant, vous ne pouvez pas valider la chaîne de requête en utilisant with dans ʻa_request` comme indiqué ci-dessous.

#Cette façon d'écrire est NG
expect(a_request(:get, /https:\/\/jsonplaceholder.typicode.com/).with(query: { userId: 2)).to have_been_made

Comment valider les chaînes de requête de tableau

Cette section décrit la méthode lorsque vous souhaitez vérifier une chaîne de requête qui spécifie plusieurs clés identiques, comme indiqué ci-dessous.

Rails par défaut

Pour les applications Rails, la valeur par défaut est d'ajouter «[]» comme indiqué ci-dessous. ([] est codé donc c'est exactement % 5B% 5D)

?userId[]=1&userId[]=2&userId[]=3

Vous pouvez spécifier un tableau dans with avec le hachage de query comme indiqué ci-dessous. Vous pouvez écrire comme des rails.

expect(
  a_request(:get, 'https://jsonplaceholder.typicode.com/todos').with(query: { userID: [1, 2, 3] })
).to have_been_made

Rails sinon par défaut

Pour les applications non-Rails telles que les API externes, la plupart des modèles n'incluent pas «[]» comme indiqué ci-dessous.

?userId=1&userId=2&userId=3

Dans ce cas, définissez le symbole : flat_array dans WebMock comme indiqué ci-dessous.

WebMock::Config.instance.query_values_notation = :flat_array

La méthode de vérification consiste à spécifier la valeur sous forme de chaîne de caractères avec le hachage query of with comme indiqué ci-dessous.

expect(
  a_request(:get, 'https://jsonplaceholder.typicode.com/todos').with(query: 'userID=1&userID=2&userID=3')
).to have_been_made

Si vous n'aimez pas écrire directement des chaînes, vous pouvez les convertir en chaînes en utilisant quelque chose comme ʻURI.encode_www_form`.

expect(
  a_request(:get, 'https://jsonplaceholder.typicode.com/todos').with(query: URI.encode_www_form(userId: [1, 2, 3]))
).to have_been_made

Si flat_array est défini, la chaîne de requête sera triée par avec

Si vous définissez WebMock :: Config.instance.query_values_notation =: flat_array, mais lors de la validation de la chaîne de requête avec avec, vous devez transmettre la valeur triée par ordre de caractères des clés.

Si vous exécutez ce qui suit dans le code testé dans le titre, la chaîne de requête sera demandée sous la forme ʻuserId = 1 & aa = 1, mais la chaîne triée ʻaa = 1 & userId = 1 est transmise à query of with. C'était inutile sans cela.

WebMock::Config.instance.query_values_notation = :flat_array

Sample.new.request(userId: 1, aa: 1)

# OK
expect(
  a_request(:get, 'https://jsonplaceholder.typicode.com/todos').with(query: 'aa=1&userId=1')
).to have_been_made

#le hachage est OK
expect(
  a_request(:get, 'https://jsonplaceholder.typicode.com/todos').with(query: { userId: 1, aa: 1 })
).to have_been_made

#C'est NG
expect(
  a_request(:get, 'https://jsonplaceholder.typicode.com/todos').with(query: 'userId=1&aa=1')
).to have_been_made

référence

https://github.com/bblimke/webmock

Recommended Posts

[RSpec] WebMock gère les expressions régulières et les chaînes de requête Array
[Java] Méthode de comparaison de chaînes de caractères et méthode de comparaison utilisant des expressions régulières
Expressions régulières
Changer de beans avec les expressions canoniques @ConditionalOnExpression et SpEL
Distinguer les entiers et les fractions avec des expressions régulières