如何在Scala测试中模拟Dispatch http客户端?

时间:2011-12-26 06:38:49

标签: scala unit-testing mocking mockito scala-dispatch

我有一些处理HTTP请求的代码,我想对它进行单元测试 因此,我试图用Scala(2.9.1.final),Mockito(1.9.0)模拟 dispatch.Http 甚至更好的 dispatch.HttpExecutor (0.8.5) -rc1)和ScalaTest(1.6.1),但即使不能使我的测试代码可编辑 在MyHttpTest中,我希望收到任何HTTP请求的某些HTTP响应:

import org.scalatest.FunSuite
import org.scalatest.mock.MockitoSugar
import org.mockito.Mockito.when
import org.mockito.Matchers.any
import dispatch._

class MyHttpTest extends FunSuite with MockitoSugar {
  test("example") {
    val httpMock = mock[HttpExecutor]
    when(httpMock.apply(any(classOf[Handler[String]]))).thenReturn("Some_HTTP_response")
  }
}

但它会产生编译错误:

error: overloaded method value thenReturn with alternatives:
(httpMock.HttpPackage[String],<repeated...>[httpMock.HttpPackage[String]])org.mockito.stubbing.OngoingStubbing[httpMock.HttpPackage[String]] <and>
(httpMock.HttpPackage[String])org.mockito.stubbing.OngoingStubbing[httpMock.HttpPackage[String]]
cannot be applied to (java.lang.String)
when(httpMock.apply(any(classOf[Handler[String]]))).thenReturn("Some_response")

那么如何模拟调度客户端?

2 个答案:

答案 0 :(得分:6)

我打算回答这个问题,建议你应该尝试ScalaMock而不是Mockito,因为我错误地认为你所遇到的问题是由Mockito引起的,而不是真正理解Scala(而ScalaMock是在斯卡拉从头开始)。但是:

  1. 这不是你的问题,
  2. 事实证明ScalaMock在尝试模拟HttpExecutor时失败,因为它不知道如何处理包对象(ExceptionListener)中定义的类型。该死的!我会尽快解决它 - 感谢你引起我的注意。
  3. 无论如何,你不能创建HttpExecutor#HttpPackage的实例,因为它是一个抽象类型。因此,为了解决这个问题,您需要扩展HttpExecutor并使HttpPackage具体化。例如:

    class MyHttpTest extends FunSuite with MockitoSugar {
      trait TestHttpExecutor extends HttpExecutor {
        type HttpPackage[T] = T
      }
      test("example") {
        val httpMock = mock[TestHttpExecutor]
        when(httpMock.apply(any(classOf[Handler[String]]))).thenReturn("Some_HTTP_response")
      }
    }
    

答案 1 :(得分:1)

我对Scala一无所知。但作为一般规则,你不应该试图嘲笑一个不属于你自己的课程;在我看来,上面的HttpExecutor就是这样一个类。

一个非常适用于可测试性的模式是开发一个类,它充当这些类的包装器,但没有自己的功能。然后写(至少)两个单独的测试类 -

  • 您的包装类的集成测试类,以确保您的 正确调用HttpExecutor;
  • 任何类使用的单元测试类 你的包装类。

集成测试类不应该有任何嘲弄。单元测试将为您的包装器类进行模拟。

如果我误解了你的问题 - 而且HttpExecutor真的是你自己的班级 - 然后再发帖,我会尝试提供不同的答案。