ScalaTest、Mockito、Guice 和 PartialMocking
ScalaTest, Mockito, Guice and PartialMocking
我正在使用 Google Guice 作为 DI 框架,我正在为我的 类 使用 Google Guice 编写单元测试。我也在尝试进行部分模拟。
这是我写的代码
class Test1 {
def test1() = "I do test1"
}
class Test2 {
def test2() = "I do test2"
}
class TestPartialMock @Inject()(t1: Test1, t2: Test2) {
def test3() = "I do test3"
def createList() : List[String] = List(t1.test1(), t2.test2(), test3())
}
我的objective是为上面的代码写一个测试用例,但我只想模拟test3
我写了这个测试用例
class TestModule extends AbstractModule with ScalaModule with MockitoSugar {
override def configure() = {
bind[Test1]
bind[Test2]
val x = mock[TestPartialMock]
when(x.test3()).thenReturn("I am mocked")
when(x.createList()).thenCallRealMethod()
bind(classOf[TestPartialMock]).toInstance(x)
}
}
class PartialMockTest extends FunSpec with Matchers {
describe("we are testing workhorse but mock test3") {
it("should return mock for test3") {
val module = new TestModule
val injector = Guice.createInjector(module)
val tpm = injector.getInstance(classOf[TestPartialMock])
val result = tpm.workHorse()
result should contain ("I do test2")
result should contain ("I do test1")
result should contain ("I am mocked")
result should not contain ("I do test3")
}
}
}
但是测试失败,依赖项出现空指针异常(调用 t1)
java.lang.NullPointerException
at TestPartialMock.createList(TestPartialMock.scala:9)
at PartialMockTest.$anonfun$new(PartialMockTest.scala:16)
at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
at org.scalatest.Transformer.apply(Transformer.scala:22)
at org.scalatest.Transformer.apply(Transformer.scala:20)
at org.scalatest.FunSpecLike$$anon.apply(FunSpecLike.scala:454)
那么我怎样才能将注入的依赖项与 test3
方法的模拟一起使用呢?
这是我的依赖项,如果你需要查看那些
"net.codingwell" %% "scala-guice" % "4.1.0",
"org.scalatest" % "scalatest_2.12" % "3.0.3",
"org.scalamock" % "scalamock-scalatest-support_2.12" % "3.5.0",
"org.mockito" % "mockito-core" % "2.7.22"
诀窍在于 Mockito 在创建模拟对象时不会调用 (base) class 的构造函数。因此 TestPartialMock
的依赖关系没有被初始化。解决此问题的最简单方法是 spy on a real object,您可以使用所需的任何配置创建
class TestModule extends AbstractModule with ScalaModule with MockitoSugar {
override def configure() = {
//bind[Test1]
//bind[Test2]
//val x = mock[TestPartialMock]
val realObject = new TestPartialMock(new Test1, new Test2)
val x = spy(realObject)
when(x.test3()).thenReturn("I am mocked")
when(x.createList()).thenCallRealMethod()
bind(classOf[TestPartialMock]).toInstance(x)
}
}
我正在使用 Google Guice 作为 DI 框架,我正在为我的 类 使用 Google Guice 编写单元测试。我也在尝试进行部分模拟。
这是我写的代码
class Test1 {
def test1() = "I do test1"
}
class Test2 {
def test2() = "I do test2"
}
class TestPartialMock @Inject()(t1: Test1, t2: Test2) {
def test3() = "I do test3"
def createList() : List[String] = List(t1.test1(), t2.test2(), test3())
}
我的objective是为上面的代码写一个测试用例,但我只想模拟test3
我写了这个测试用例
class TestModule extends AbstractModule with ScalaModule with MockitoSugar {
override def configure() = {
bind[Test1]
bind[Test2]
val x = mock[TestPartialMock]
when(x.test3()).thenReturn("I am mocked")
when(x.createList()).thenCallRealMethod()
bind(classOf[TestPartialMock]).toInstance(x)
}
}
class PartialMockTest extends FunSpec with Matchers {
describe("we are testing workhorse but mock test3") {
it("should return mock for test3") {
val module = new TestModule
val injector = Guice.createInjector(module)
val tpm = injector.getInstance(classOf[TestPartialMock])
val result = tpm.workHorse()
result should contain ("I do test2")
result should contain ("I do test1")
result should contain ("I am mocked")
result should not contain ("I do test3")
}
}
}
但是测试失败,依赖项出现空指针异常(调用 t1)
java.lang.NullPointerException
at TestPartialMock.createList(TestPartialMock.scala:9)
at PartialMockTest.$anonfun$new(PartialMockTest.scala:16)
at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
at org.scalatest.Transformer.apply(Transformer.scala:22)
at org.scalatest.Transformer.apply(Transformer.scala:20)
at org.scalatest.FunSpecLike$$anon.apply(FunSpecLike.scala:454)
那么我怎样才能将注入的依赖项与 test3
方法的模拟一起使用呢?
这是我的依赖项,如果你需要查看那些
"net.codingwell" %% "scala-guice" % "4.1.0",
"org.scalatest" % "scalatest_2.12" % "3.0.3",
"org.scalamock" % "scalamock-scalatest-support_2.12" % "3.5.0",
"org.mockito" % "mockito-core" % "2.7.22"
诀窍在于 Mockito 在创建模拟对象时不会调用 (base) class 的构造函数。因此 TestPartialMock
的依赖关系没有被初始化。解决此问题的最简单方法是 spy on a real object,您可以使用所需的任何配置创建
class TestModule extends AbstractModule with ScalaModule with MockitoSugar {
override def configure() = {
//bind[Test1]
//bind[Test2]
//val x = mock[TestPartialMock]
val realObject = new TestPartialMock(new Test1, new Test2)
val x = spy(realObject)
when(x.test3()).thenReturn("I am mocked")
when(x.createList()).thenCallRealMethod()
bind(classOf[TestPartialMock]).toInstance(x)
}
}