2017-05-04 60 views
3

我用Scala編寫,吉斯,和的Mockito ScalaTest斯卡拉吉斯的Mockito和部分嘲諷....方法被調用兩次

import javax.inject.Singleton 
import com.google.inject.Inject 
@Singleton 
class TestPartialMock @Inject()(t1: Test1, t2: Test2) { 
    def test3() = "I do test3" 
    def workHorse() : List[String] = { 
     println("+++++ came inside ++++++++") 
     List(t1.test1(), t2.test2(), test3()) 
    } 
} 


class MainModule extends ScalaModule { 
    override def configure() = { 
     bind[Test1] 
     bind[Test2] 
     bind[TestPartialMock] 
    } 
} 

,我已經寫單元測試用例部分嘲諷

下面的代碼
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") 
     } 
    } 
} 

class TestModule extends AbstractModule with ScalaModule with MockitoSugar { 
    override def configure() = { 
     val module = new MainModule() 
     val injector = Guice.createInjector(module) 
     val realobject = injector.getInstance(classOf[TestPartialMock]) 
     val x = spy(realobject) 
     when(x.test3()).thenReturn("I am mocked") 
     when(x.workHorse()).thenCallRealMethod() 
     bind(classOf[TestPartialMock]).toInstance(x) 
    } 
} 

我的測試成功,我可以看到它嘲笑正確的方法集合並調用正確的方法集的實際實現。但是,當我看到在輸出我看到

info] Compiling 5 Scala sources to /Users/IdeaProjects/GuicePartialMock/target/scala-2.12/classes... 
[info] Compiling 1 Scala source to /Users/IdeaProjects/GuicePartialMock/target/scala-2.12/test-classes... 
+++++ came inside ++++++++ 
+++++ came inside ++++++++ 
[info] PartialMockTest: 
[info] we are testing workhorse but mock test3 
[info] - should return mock for test3 
[info] Run completed in 2 seconds, 92 milliseconds. 

爲什麼我看到print語句came inside兩次?

編輯::

基於Tavian的意見

...這是當你在問題的標題提及的工作

class TestModule extends AbstractModule with ScalaModule with MockitoSugar { 
    override def configure() = { 
     val module = new MainModule() 
     val injector = Guice.createInjector(module) 
     val realobject = injector.getInstance(classOf[TestPartialMock]) 
     val x = spy(realobject) 
     when(x.test3()).thenReturn("I am mocked") 
     bind(classOf[TestPartialMock]).toInstance(x) 
    } 
} 
+1

對於Mockito間諜,'when(x.workHorse())'已經調用真正的'workHorse()'方法。事實上,不需要'.thenCallRealMethod()',因爲這是間諜的默認行爲。 –

回答

2

對於間諜,你需要小心表情像

when(x.workHorse()).thenCallRealMethod() 

因爲x.workHorse()真的是在這個表達式被調用! x並不「知道」,這是一個when()裏面調用,爲表達降低到這樣的事情:

tmp1 = x.workHorse(); 
tmp2 = when(tmp1); 
tmp3 = tmp2.thenCallRealMethod(); 

相反,你可以寫

doCallRealMethod().when(x).workHorse() 

,這將打壓的調用實際workHorse()實施。

但是,你不需要爲這個例子做任何這個—調用真正的方法是間諜的默認行爲。

+0

我試過你的建議。我用新的代碼編輯了我的帖子。但我仍然看到兩個調用。 –

+0

但你沒有采取我的建議('doCallRealMethod()。when(x).workHorse()') –

+0

是的,它的工作原理!!!!! –

-1

最後的代碼,你有3項技術的組合。其實有4項技術,包括用於運行測試的構建工具。可以通過

1)拆下吉斯隔離問題並實例一切直接

2)執行命令代碼作爲一個簡單的應用程序,而不是運行由SBT/gradle這個/行家測試。

此外,將堆棧跟蹤與came inside消息一起打印以查找調用者也是有意義的。

+0

刪除了與Guice一起使用的所有內容。 thead的重點是我想和Guice一起做。這是問題的關鍵。否則它很簡單。 –