5

我有一些处理 HTTP 请求的代码,我想对它进行单元测试。
因此,我试图用 Scala (2.9.1.final)、Mockito (1.9.0-rc1) 和 ScalaTest (1.6.1) 模拟dispatch.Http甚至更好的dispatch.HttpExecutor (0.8.5),但甚至可以' t 使我的测试代码可编译。
在 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")

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

4

2 回答 2

6

我打算用你应该尝试ScalaMock而不是 Mockito的建议来回答这个问题,因为我错误地认为你遇到的问题是由于 Mockito 没有真正理解 Scala(而 ScalaMock 是从头开始在 Scala 中创建的)。然而:

  1. 那不是你的问题,而且
  2. 事实证明,ScalaMock 在尝试模拟时会失败,HttpExecutor因为它不知道如何处理包对象 ( ExceptionListener) 中定义的类型。该死!我会尽快修复它 - 感谢您引起我的注意。

无论如何,你不能创建一个实例,HttpExecutor#HttpPackage因为它是一个抽象类型。因此,要解决它,您需要扩展HttpExecutorHttpPackage具体化。例如:

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")
  }
}
于 2011-12-26T18:10:44.827 回答
1

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

一种对可测试性非常有效的模式是开发一个类,该类充当此类类的包装器,但没有自己的功能。然后编写(至少)两个单独的测试类 -

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

集成测试类根本不应该有任何嘲笑。单元测试将为您的包装类提供一个模拟。

如果我误解了你的问题——而且 HttpExecutor 确实是你自己的课程——然后再发一次,我会尝试提供不同的答案。

于 2011-12-26T09:01:45.663 回答