Created
July 17, 2012 09:48
-
-
Save arussel/3128411 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.getpinsights.qa | |
import dispatch._ | |
import org.apache.http._ | |
import client.methods.HttpGet | |
import entity.InputStreamEntity | |
import message.{BasicHttpResponse, BasicStatusLine} | |
import client.HttpClient | |
import org.specs2.mock.Mockito | |
import org.mockito.Mockito._ | |
import java.io.{InputStream, ByteArrayInputStream} | |
import org.apache.commons.io.IOUtils | |
import org.mockito.stubbing.Answer | |
import org.mockito.invocation.InvocationOnMock | |
/** | |
* MockHttp allows to mock dispatch.http and to server files directly from filesystem | |
* without any network connection. | |
* | |
* To server files sequentially, use #getMockHttp(String) or #getMockHttp(List[String]) | |
* To server files depending on the request URI use #getMockHttp(Map[String,String]) | |
* | |
* The filename needs to start with '/'. | |
*/ | |
trait MockHttp extends Mockito { | |
val protocolVersion = new ProtocolVersion("HTTP", 1, 1) | |
/** | |
* Returns a Http that will serve the file 'file' at each invocation | |
* @param file the filename starting with '/' | |
* @return a dispatch.Http object | |
*/ | |
def getMockHttp(file: String): Http = getMockHttp(List(file)) | |
/** | |
* Returns a Http that will check the uri of the request and: | |
* - if the uri is a key in 'choices' will return a file using the value as filname | |
* - if the uri is not a key in 'choices' will throw an error. | |
* @param choices a map of key, a uri starting by '/' and the corresponding answer as value, | |
* a filename starting with '/' | |
* @return a dispatch.Http object | |
*/ | |
def getMockHttp(choices: Map[String, String]): Http = { | |
val httpClient = mock(manifest[HttpClient]) | |
when(httpClient.execute(any[HttpHost], any[HttpGet])).then(new Answer[HttpResponse] { | |
def answer(iom: InvocationOnMock): HttpResponse = { | |
val args = iom.getArguments | |
val get = args(1).asInstanceOf[HttpGet] | |
val uri = get.getURI.getPath | |
if (choices.isDefinedAt(uri)) { | |
val is = getClass.getResourceAsStream(choices(uri)) | |
val bytes = IOUtils.toByteArray(is) | |
val bais = new ByteArrayInputStream(bytes) | |
val r = new BasicHttpResponse(protocolVersion, 200, "") | |
r.setEntity(new InputStreamEntity(bais, bytes.length)) | |
r | |
} else { | |
throw new Error("A response file was not provided for uri: " + uri) | |
} | |
} | |
}) | |
val http = new Http with thread.Safety { | |
override def make_client: HttpClient = httpClient | |
} | |
http | |
} | |
/** | |
* Returns a Http that will serve the files 'files' sequentially. When all files | |
* have been served, it will serve the last one forever. | |
* @param files a list of filename starting with '/' | |
* @return a dispatch.Http object | |
*/ | |
def getMockHttp(files: List[String]): Http = { | |
val response = mock(manifest[HttpResponse]) | |
val entity: HttpEntity = mock(manifest[HttpEntity]) | |
val httpClient: HttpClient = mock(manifest[HttpClient]) | |
when(response.getEntity).thenReturn(entity) | |
when(response.getStatusLine).thenReturn(new BasicStatusLine(protocolVersion, 200, "")) | |
when(httpClient.execute(any[HttpHost], any[HttpGet])).then(new Answer[HttpResponse] { | |
def answer(invocation: InvocationOnMock) = response | |
}) | |
class AnswerInputStream extends Answer[InputStream] { | |
var counter = 0 | |
override def answer(invocation: InvocationOnMock) = { | |
val filename = if (counter >= files.size) files.last else files(counter) | |
val is = getClass.getResourceAsStream(filename) | |
val bytes: Array[Byte] = IOUtils.toByteArray(is) | |
counter += 1 | |
new ByteArrayInputStream(bytes) | |
} | |
} | |
when(entity.getContent).then(new AnswerInputStream) | |
val http = new Http with thread.Safety { | |
override def make_client: HttpClient = httpClient | |
} | |
http | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment