カスタム仕様予想


カスタム期待には2つの部分があります.
  • 期待論理を実行するクラス
  • Specsで使用され、クラス
  • を初期化して返すメソッドです.

    カスタム予想クラス
    実装するメソッド
  • #matchは、期待ロジック
  • を実行する
  • #failure_message - #matchが失敗し、#shouldが使用されたときのエラーメッセージ
  • #negative_failure_message - #matchが失敗し、#should_notが使用されたときのエラーメッセージ
  • これらのメソッドのうちの3つは1つの引数を取ります、#shouldまたは#should_notが呼ばれたオブジェクト.したがって、期待がresult.should be_nilならば、それらの方法は議論としてresultを取るでしょう.HTTP ::Requestが予想される経路を持っているかどうかをチェックする例を示します.
    class HavePathExpectation
      def initialize(@expected_path : String)
      end
    
      def match(request : HTTP::Request)
        request.path == @expected_path
      end
    
      def failure_message(request : HTTP::Request)
        <<-MSG
        Expected request to have path: #{@expected_path}
                               actual: #{request.path}
        MSG
      end
    
      def negative_failure_message(request : HTTP::Request)
        "Expected request to not have path: #{request.path}"
      end
    end
    

    カスタム期待メソッド
    これらはグローバルな方法であり、ユーザが呼ぶ期待です.ライブラリは、それらのspec_helper.crに含めるユーザのために単一のモジュールにそれらを置かなければなりません.クラスを上記のクラスから使用するには、次の手順に従います
    module MyLibrary::Expectations
      def have_path(expected_path : String)
        HavePathExpectation.new(expected_path)
      end
    end
    
    # in spec_helper.cr
    include MyLibrary::Expectations
    
    # in a spec
    request.should have_path("/users")
    
    すべてのメソッドは、必要な場合は引数を取り、初期化された期待クラスを返します.
    タイプは、カスタム期待で指定するのに本当に役に立ちます.クラスメソッドパラメーターの型は、期待を使用するときに制限されます.上記のクラスは#shouldHTTP::Requestが呼び出されたときのみに制限され、期待値は期待値として渡されるものを制限します.

    狂気
    私はまだそれを実装する機会を持っていませんでしたが、#should以来、それらの3つのメソッドを呼び出すことができるいくつかのオブジェクトを期待しているので、1つだけ期待メソッドで停止する必要はありません.メソッドが常にselfを最後に返す方法を使用すると、本当に楽しいDSLを作ることができます.リクエストパスについての特定の期待クラスの代わりに、リクエストの異なる部分をチェックするために更新できる一般的なリクエスト検証クラスであることを想像してください.
    class RequestExpectation
      @path : String?
      @request_method : String?
      @errors = [] of String
    
      def match(request : HTTP::Request)
        if expected_path = @path && request.path != expected_path
          @errors << "Expected path to be #{expected_path} but was #{request.path}"
          return false 
        end
    
        if expected_method = @request_method && request.method != expected_method
          @errors << "Expected request method to be #{expected_method} but was #{request.method}"
          return false
        end
    
        true
      end
    
      def with_path(expected_path : String)
        @path = expected_path
        self
      end
    
      def with_method(expected_method : String)
        @request_method = expected_method
        self
      end
    
      def failure_message(request : HTTP::Request)
        # not implemented for brevity
      end
    
      def negative_failure_message(request : HTTP::Request)
        # not implemented for brevity
      end
    end
    
    そして、それに応じて期待を更新する必要があります
    module MyLibrary::Expectations
      def have_path(expected_path : String)
        HavePathExpectation.new.with_path(expected_path)
      end
    
      def have_method(expected_method : String)
        HavePathExpectation.new.with_method(expected_method)
      end
    end
    
    今、あなたは必要な部分を検証するために期待を作成することができます.
    request.should have_method("GET")
    
    request.should have_path("/users/123").with_method("DELETE")
    
    期待が非常に特異的であるが、より詳細を提供した後にヘルパー方法でより広い期待を持っていると想像するので、これは最高の例であったかもしれません.
    EmailClient.should have_sent_emails
      .to("[email protected]")
      .with_subject("Subscription Invoice")
      .with_cc("[email protected]")
      .with_email_template(SubscriptionInvoice)
    
    それは少し仕事がかかりますが、それはかなりクールだと思う!