2017-10-20 22 views
3

私はSMSを送信するために次のコードを使用しています。模擬twilioテストクライアント

from twilio.rest import Client 
from django.conf import settings 

def send_sms(phone, content=generate_sms_code()): 
    client = Client(settings.ACCOUNT_SID, settings.AUTH_TOKEN) 
    return client.messages.create(
     to=phone, 
     from_=settings.FROM_DEFAULT_NUMBER, 
     body=content) 

twilio apiをモックする正しい方法は何ですか?

私はあなたがAPIを使用してtwilioのSMS機能をテストしたい場合、あなたはそれをテストするために自由twilioアカウントを作成することができますtwilio6.5.2

+0

twilioから無料のapi-keyを登録することができます。twillioでアカウントを作成して遊ぶことができます。 https://support.twilio.com/hc/en-us/articles/223136107-How-does-Twilio-s-Free-Trial-work-さまざまなtwilioシナリオのコードをテストすることを意図している場合は、ユニット/エンドツーエンドのテスト用にMockingライブラリを使用する必要があります –

答えて

4

を参照してください。

  1. 使用偽twilioクライアントは、あなたのコード
  2. 使用をテストユニットに使用しますテストアカウントを持つ実際のクライアント

単体テストの場合、通常はアプローチ1が良いアイデアです。たとえば、テストをオフラインで実行できますテストはより速く実行されます。また、コードをテストする必要がありますが、アプローチ2ではtwilio自体もテストします。

これはもう1つの問題をもたらします。つまり、偽のクライアントが実際のクライアントに十分近づいてテストを有効にする方法を教えてください。 twilioはそのようなテストクライアントをリリースして維持するのが最善のケースですが、そのように見えません。

あなたができることはアプローチを組み合わせることです:偽のクライアント(アプローチ1)を持ち、偽のクライアントが実際のものと同じ動作をすることを検証するいくつかのテストがあります。

しかし、アプローチ1から始めることができます。テストクライアント(通常はスーパーシンプルなもの)を構築し、実際のクライアントに十分近づける必要があります(実際のクライアントに切り替えて、あなたのテストはまだ動作しています)。

ここで危険なのは、twilio側でいくつかのAPIの変更があった場合でも、実際のアプリケーションが壊れてもテストは引き続き実行されるということです。 一方、テストが失敗したとしても、実際のアプリはまだ壊れているので、このシナリオではアプリを本当に保護することはできません。ここで

は私達があなたのコードのためのテストクライアントを作ることができる方法です:

class TwilioTestClient: 

    def __init__(self, sid, token): 
     self.sid = sid 
     self.token = token 
     self.messages = TwillioTestClientMessages() 

class TwillioTestClientMessages: 

    self.created = [] 

    def create(self, to, from_, body): 
     self.created.append({ 
      'to': to, 
      'from_': from_, 
      'body': body 
     }) 

そして、あなたのテストであなたは、このような何かを行うことができます。

import twilio 
# Replace real client with our test client 
twilio.Client = TwilioTestClient 

// invoke your code 
send_sms(phone, content) 

assert TwillioTestClientMessages.created == [{ 
    'to': phone, 
    'from_': settings.DEFAULT_NUMBER, 
    'body': content 
}) 

これはさらに、単純化されたアプローチでありますmock libraryを使用してテストクライアントを作成することができます。

実際のHTTP要求をブロックし、パラメータを記録/レスポンスをエミュレートするためだけに、実際のtwilioクライアントにパッチを適用することができます。 あなたがモックする方法(またはメソッド)を見つけるためにtwilioクライアントのソースコードに調べる必要がありますが、ここで私がrequests図書館のSession.request方法をあざけることで モックFacebookのグラフの応答に使用されてきた同様のアプローチです:

mock_facebook_data = { 
    'id': 'test_id', 
    'first_name': 'First Name', 
    'last_name': 'Last Name' 
} 

def get_facebook_data(self, method, url, **kwargs): 
    # Make sure we are mocking the expected request. 
    assert method == 'get' 
    assert url == (
     'https://graph.facebook.com/me?fields=first_name,id,' 
     'last_name&access_token={}'.format(facebook_access_token) 
    ) 

    class ResponseMock: 

     def __init__(self, data): 
      self.data = data 
      self.status_code = 200 

     def json(self): 
      return self.data 

    return ResponseMock(mock_facebook_data) 

monkeypatch.setattr('requests.sessions.Session.request', get_facebook_data) 

今、アプリがFacebook APIからデータを取得しようとすると、代わりに静的データが取得され、そのデータはResponseMockオブジェクトにラップされ、実際のリクエストから得られる情報は最小限に抑えられます。

この記事をチェック:Unit Testing Your Twilio App Using Python’s Flask and Nose私が理解しているように、彼らはユニットテストのために実際のクライアントを使用していますが、統合のもう一つの側面、つまりTwilio側から呼び出されているコードをテストする方法についても言及しています。 この場合、Twilioサーバをエミュレートする必要があります。そのようなエミュレーションの例が記事にあります。

1

を使用しています。

しかし、アカウントSID、認証トークンなどに環境固有の値を使用することをお勧めします。テスト/開発環境から本番環境を分離したいので、同じコードが異なるtwilioアカウントを持つ環境。コメントで@txfunによって示唆されるように

、ここで使用できる2つのアプローチがありtwilio Free accountリンク