Home > database >  Writing Unit Test of Interceptors
Writing Unit Test of Interceptors

Time:11-27

I am working on a project where I need to write an interceptor which basically modifies headers. Below is a similar code

class AuthRequestInterceptor implements Interceptor {
  @Override public Response intercept(Interceptor.Chain chain) throws IOException {
        Request original = chain.request();

        // Request customization: add request headers
        Request.Builder requestBuilder = original.newBuilder()
                .header("Authorization", "auth-value"); 
    
        Request request = requestBuilder.build();
        return chain.proceed(request);
  }
}

I want to test if Authorization has been added to the request header by the interceptor. Here is the code for testing

class AuthRequestInterceptorTest extends Specification {
    AuthRequestInterceptor authRequestInterceptor = new AuthRequestInterceptor();
    OkHttpClient okHttpClient = new OkHttpClient();

    void setup() {
        try {
            okHttpClient = new OkHttpClient()
                .newBuilder()
                .addInterceptor(authRequestInterceptor)
                .build();
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            throw new WebClientException(e)
        }
    }


    def "Get Authorization in to header"() {

        given:
        HashMap<String, String> headers = new HashMap<>()

        when:
        Request mockRequest = new Request.Builder()
            .url("http://1.1.1.1/heath-check")
            .headers(Headers.of(headers))
            .build()

       Response res = okHttpClient.newCall(mockRequest).execute()

        then:
        res.headers("Authorization")
    }
}

The test is failing so I debugged the Response returned by AuthRequestInterceptor and it is as below

Response{protocol=h2, code=200, message=, url=https://1.1.1.1/}

I want to test if the Authorization key is added in request headers, But I an able to get Response only and not able to figure out how to get the request header

CodePudding user response:

Helper class:

package de.scrum_master.stackoverflow.q74575745;

class WebClientException extends RuntimeException {
  public WebClientException(Throwable cause) {
    super(cause);
  }
}

Class under test:

package de.scrum_master.stackoverflow.q74575745;

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;

class AuthRequestInterceptor implements Interceptor {
  @Override
  public Response intercept(Interceptor.Chain chain) throws IOException {
    Request original = chain.request();

    // Request customization: add request headers
    Request.Builder requestBuilder = original.newBuilder()
      .header("Authorization", "auth-value");

    Request request = requestBuilder.build();
    return chain.proceed(request);
  }
}

Spock specification:

In order to test your interceptor in isolation, just mock the interceptor chain parameter, making sure that it returns a request without headers. Then verify that the proceed(Request) method is called with a request parameter containing the header you expect.

package de.scrum_master.stackoverflow.q74575745

import okhttp3.Interceptor
import okhttp3.Request
import spock.lang.Specification

class AuthRequestInterceptorTest extends Specification {
  def "request contains authorization header"() {
    given: "a mock interceptor chain returning a prepared request without headers"
    def chain = Mock(Interceptor.Chain) {
      request() >> new Request.Builder()
        .url("http://1.1.1.1/heath-check")
        .build()
    }

    when: "running the interceptor under test"
    new AuthRequestInterceptor().intercept(chain)

    then: "the expected authorization header is added to the request before proceeding"
    1 * chain.proceed({ Request request -> request.headers("Authorization") == ["auth-value"] })
  }
}

Try it in the Groovy Web Console.

You probably want to learn about Spock argument constraints.

  • Related