Проблемы с тестированием akka http cache - PullRequest
0 голосов
/ 14 марта 2019

Я использую кеш Akka HTTP для кеширования своих результатов.Но я сталкиваюсь с проблемой, чтобы проверить это.

class GoogleAnalyticsController @Inject()(cache: Cache[String, HttpResponse],
                                          googleAnalyticsApi: GoogleAnalyticsTrait,
                                          googleAnalyticsHelper: GoogleAnalyticsHelper)
                                         (implicit system: ActorSystem, materializer: ActorMaterializer) {


def routes: Route =

      post {
        pathPrefix("pageviews") {
          path("clients" / Segment) { accountsClientId =>
            entity(as[GoogleAnalyticsMetricsRequest]) { googleAnalyticsMetricsRequest =>
         val googleAnalyticsMetricsKey = "key"
         complete(
           cache.getOrLoad(googleAnalyticsMetricsKey, _ => getGoogleAnalyticsMetricsData(accountsClientId, googleAnalyticsMetricsRequest))
          ) 
         }

       }
     }
   }

 private def getGoogleAnalyticsMetricsData(accountsClientId: String,
                                            request: GoogleAnalyticsMetricsRequest) = {
    val payload = generate(request)
    val response = googleAnalyticsApi.googleAnalyticsMetricResponseHandler(accountsClientId, payload) // response from another microservice
googleAnalyticsHelper.googleAnalyticsMetricResponseHandler(
       googleAnalyticsMetricsRequest.metricName, response)
}

}

class GoogleAnalyticsHelper extends LoggingHelper {

  def googleAnalyticsMetricResponseHandler(metricName: String, response: Either[Throwable, Long]): Future[HttpResponse] =
    response.fold({ error =>
      logger.error(s"An exception has occurred while getting $metricName from behavior service and error is ${error.getMessage}")
      Marshal(FailureResponse(error.getMessage)).to[HttpResponse].map(httpResponse => httpResponse.copy(status = StatusCodes.InternalServerError))
    }, value =>
      Marshal(MetricResponse(metricName, value)).to[HttpResponse].map(httpResponse => httpResponse.copy(status = StatusCodes.OK))
    )

}

Контрольный пример: совместное использование только соответствующей части

"get success metric response for " + pageviews + " metric of given accounts client id" in { fixture =>
      import fixture._

      val metricResponse = MetricResponse(pageviews, 1)
      val eventualHttpResponse = Marshal(metricResponse).to[HttpResponse].map(httpResponse => httpResponse.copy(status = StatusCodes.OK))

      when(cache.getOrLoad(anyString, any[String => Future[HttpResponse]].apply)).thenReturn(eventualHttpResponse)
      when(googleAnalyticsApi.getDataFromGoogleAnalytics(accountsClientId, generate(GoogleAnalyticsRequest(startDate, endDate, pageviews))))
        .thenReturn(ApiResult[Long](Some("1"), None))
      when(googleAnalyticsHelper.googleAnalyticsMetricResponseHandler(pageviews, Right(1))).thenReturn(eventualHttpResponse)

      Post(s"/pageviews/clients/$accountsClientId").withEntity(requestEntity) ~>
        googleAnalyticsController.routes ~> check {
        status shouldEqual StatusCodes.OK
        responseAs[String] shouldEqual generate(metricResponse)
      }
    }

Делая это, я лучше всего проверю, есть ли в кеше ключно не в состоянии проверить, не попал ли в кеш.В покрытии кода он пропускает следующую выделенную часть

cache.getOrLoad (googleAnalyticsMetricsKey, _ => getGoogleAnalyticsMetricsData (accountsClientId, googleAnalyticsMetricsRequest) )

* 1013Возникла проблема с дизайном. Пожалуйста, не стесняйтесь указывать мне, как сделать мой дизайн тестируемым.

Заранее спасибо.

1 Ответ

2 голосов
/ 14 марта 2019

Я думаю, вам не нужно издеваться над кешем.Вы должны создать реальный объект для кеша вместо смоделированного.

То, что вы сделали, это то, что вы смоделировали кеш, в этом случае выделенная часть не будет вызываться, поскольку вы предоставляете смоделированное значение.В следующей заглушке при обнаружении cache.getOrLoad возвращается eventualHttpResponse:

when(cache.getOrLoad(anyString, any[String => Future[HttpResponse]].apply)).thenReturn(eventualHttpResponse)

и, следовательно, функция getGoogleAnalyticsMetricsData(accountsClientId, googleAnalyticsMetricsRequest) никогда не вызывается.

...