在 scalatest 中测试方法时,是否可以模拟/存根在方法调用中实例化的对象? [英] When testing a method in scalatest, is it possible to mock/stub an object which is instantiated inside the method call?

查看:71
本文介绍了在 scalatest 中测试方法时,是否可以模拟/存根在方法调用中实例化的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在我正在为一个方法编写一个测试套件,该方法接受一个字符串,实例化一个数据库端点,然后用字符串查询端点.然后它接受这个响应,对其执行几次转换,并最终返回它.大致是这样的:

Right now I am writing a testing suite for a method which takes in a string, instantiates a database endpoint, and then queries the endpoint with the string. It then takes this response, performs several transformations to it, and ultimately returns it. It looks roughly like this :

method(s: String){
    dbEndpoint database = new dbEndpoint()
    DataFrame df = database.read(s)
    df.transform(...)
}

由于我已经为数据库端点编写了测试并且确信它足够健壮,所以我只关心确保在数据库查询之后发生的转换逻辑是正确的.因此,我想存根端点,以便 endpoint.read() 返回少量数据,可以轻松验证其转换的正确性.

Since I have already written tests for the database endpoint and am confident that it is sufficiently robust, I am only concerned with ensuring that the transformation logic that occurs after the database query is correct. As a result, I want to stub the endpoint such that endpoint.read() returns a small amount of data whose transformation can easily be verified for correctness.

我的理解是不可能存根这个特定的端点,因为我没有在方法范围之外引用它.我错了吗?有什么方法可以让我从外部对数据库进行存根/模拟(不改变方法)?

It is my understanding that it is not possible to stub this specific endpoint, since I have no reference to it outside of the scope of the method. Am I wrong? Is there some way that I could go about stubbing/mocking the database from the outside (without changing the method)?

推荐答案

警告:使用 PowerMock 确实可以做到这一点,尽管它只能作为@bruno-bonanno 建议的最后手段来完成.

WARNING: This is indeed possible using PowerMock, although it should be done only as last resort as suggested by @bruno-bonanno.

PowerMock 支持模拟硬连线的本地范围依赖项,例如 dbEndpoint,使用以下三个工具:

PowerMock supports mocking of hardwired local scope dependencies, such as dbEndpoint, using the following three facilites:

  • PowerMockito.whenNew
  • @RunWith
  • @PrepareForTest

这是一个使用 Scala、PowerMock、Mockito 和 JUnit 的工作示例:

Here is a working example using Scala, PowerMock, Mockito and JUnit:

import org.scalatest.junit.AssertionsForJUnit
import org.junit.Assert._
import org.junit.Test
import org.junit.runner.RunWith
import org.powermock.api.mockito.PowerMockito
import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner
import org.mockito.Mockito._

class Hardwired {
  def f(i: Int): String = s"I am a real Hardwired instance"
}

class Foo {
  def bar(i: Int): String = {
    val localHardwiredInstance = new Hardwired()
    localHardwiredInstance.f(i)
  }
}

@RunWith(classOf[PowerMockRunner])
@PrepareForTest(Array(classOf[Foo]))
class ExampleSuite extends AssertionsForJUnit {
  @Test def mockLocalHardwiredDependency() {
    val hardwiredMock = mock(classOf[Hardwired])
    when(hardwiredMock.f(3)).thenReturn("I am a mocked Hardwired instance")
    PowerMockito.whenNew(classOf[Hardwired]).withNoArguments().thenReturn(hardwiredMock)
    val foo = new Foo
    assertEquals("I am a mocked Hardwired instance", foo.bar(3))
  }
}

build.sbt:

libraryDependencies ++= Seq(
  scalaTest % Test,
  "org.powermock" % "powermock-api-mockito" % "1.7.4" % Test,
  "org.powermock" % "powermock-core" % "1.7.4" % Test,
  "org.powermock" % "powermock-module-junit4" % "1.7.4" % Test,
  "org.mockito" % "mockito-core" % "1.10.19" % Test,
  "com.novocode" % "junit-interface" % "0.11" % Test,
),
testOptions += Tests.Argument(TestFrameworks.JUnit, "-v")

我不确定如何使用 ScalaTest 运行它 - 我相信我们需要一个相应的 PowerMockRunner,但是目前我找不到.

I am unsure how to run it with ScalaTest - I believe we need a corresponding PowerMockRunner, however currently I was unable to find one.

这篇关于在 scalatest 中测试方法时,是否可以模拟/存根在方法调用中实例化的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆