当前位置:  开发笔记 > 编程语言 > 正文

Scala中的单元测试助手或非接口特征

如何解决《Scala中的单元测试助手或非接口特征》经验,为你挑选了1个好方法。

这个问题是关于处理混合非接口特征的类的测试,这是包含一些功能的特征.在测试时,类功能应该与混合特性(假设单独测试)提供的功能隔离.

我有一个简单的Crawler类,它依赖于HttpConnection和一HttpHelpers组实用函数.现在让我们关注HttpHelpers.

在Java中,HttpHelpers可能是一个实用程序类,并且可以将其单例作为依赖项传递给Crawler,无论是手动还是使用某些IoC框架.测试Crawler非常简单,因为依赖项很容易被模拟.

在Scala中,似乎辅助特征是组合功能的更优选方式.实际上,它更容易使用(扩展时自动导入命名空间的方法,可以withResponse ...代替使用httpHelper.withResponse ...等).但它如何影响测试?

这是我提出的解决方案,但遗憾的是它将一些样板提升到测试端.

助手特质:

trait HttpHelpers {
  val httpClient: HttpClient
  protected def withResponse[A](resp: HttpResponse)(fun: HttpResponse => A): A = // ...
  protected def makeGetRequest(url: String): HttpResponse = // ...
}

要测试的代码:

class Crawler(val httpClient: HttpClient) extends HttpHelpers {
  // ...
}

测试:

// Mock support trait
// 1) Opens up protected trait methods to public (to be able to mock their invocation)
// 2) Forwards methods to the mock object (abstract yet)
trait MockHttpHelpers extends HttpHelpers {
  val myMock: MockHttpHelpers
  override def makeGetRequest(url: String): HttpResponse = myMock.makeGetRequest(url)
}

// Create our mock using the support trait
val helpersMock = Mockito.mock(classOf[MockHttpHelpers])

// Now we can do some mocking
val mockRequest = // ...
Mockito when (helpersMock.makeGetRequest(Matchers.anyString())) thenReturn mockRequest

// Override Crawler with the mocked helper functionality
class TestCrawler extends Crawler(httpClient) with MockHttpHelpers {
  val myMock = helpersMock
}

// Now we can test
val crawler = new TestCrawler()
crawler.someMethodToTest()

这种方法可以完成这项工作,但需要为每个帮助程序特征设置一个模拟支持特性,这有点单调乏味.但是,我看不到任何其他方式可以工作.

这是正确的方法吗?

如果是,它的目标是否可以更有效地达到(语法魔术,编译器插件等)?

欢迎任何反馈.谢谢!



1> paradigmatic..:

您可以编写一个Helper模拟特征,它应HttpHelpers与模拟等效项混合并覆盖其方法:

trait HttpHelpersMock { this: HttpHelpers =>

  //MOCK IMPLEMENTATION
  override protected def withResponse[A](resp: HttpResponse)(fun: HttpResponse => A): A = // ...

  //MOCK IMPLEMENTATION
  override protected def makeGetRequest(url: String): HttpResponse = // ...
}

然后,在测试爬虫时,在实例化时混合模拟特征:

val crawlerTestee = new Crawler(x) with HttpHelpersMock

而mock方法只会替换实例中的helper方法crawlerTestee.

编辑:我不认为测试类如何与辅助特征交互是一个好主意.在我看来,您应该测试Crawler行为而不是其内部实现细节.实现可以改变,但行为应尽可能保持稳定.我上面描述的过程允许您覆盖辅助方法,使其确定性并避免真正的网络,从而帮助和加快测试.

但是,我认为测试Helper本身是有意义的,因为它可以在其他地方重复使用并具有适当的行为.


我读到的关于单身人士的大部分担忧都与国家分享有关.如果你的助手只是方法的无状态"模块",那么它们只是实现机制.所以你应该只关注其他方法的行为.但是,如果特征作为受"helpee"对象影响的状态,你应该担心嘲笑它.
推荐阅读
小妖694_807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有