2017-05-08 72 views
0

我使用mockito和Spring Boot。在Runnable中使用模擬對象時,我發現這些存根不起作用。Mockito的模擬不能在可運行

下面是代碼示例:

@Component 
public class TheClassIWantTest { 
    @Autowired 
    private ADependency aDependency; 

    @Autowired 
    private ThreadPoolTaskExecutor executor; 

    public void theMethodIWantTest { 
     executor.execute(new Runnable() { 
      @Override 
      public void run() { 
       Integer result = aDependency.doSomething(); // result should be 111, but it's null 
      } 
     }) 
    } 
} 

單元測試:

@RunWith(SpringRunner.class) 
@SpringBootTest(classes = TestApplication.class) 
@FixMethodOrder(value = MethodSorters.NAME_ASCENDING) 
public class TheTest { 

    @Autowired 
    private TheClassIWantTest theClassIWantTest; 

    @MockBean 
    private ADependency aDependency; 

    @Test 
    public void testTheMethod() { 
     Ingeter testResult = 1; 
     when(aDependency.doSomething()).thenReturn(111); // this stub doesn't work... 

     theClassIWantTest.theMethodIWantTest(); 
    } 
} 

我期待aDependency.doSomething()將返回111,因爲我定義在測試情況下短截線,但result是空值。

如果我刪除的

executor.execute(new Runnable() { 
     @Override 
     public void run() { 

線把異步運行的方法,以一個正常的同步方法,存根做工不錯,e.g result == 111

這讓我覺得存根在可運行時不再起作用。

我該如何解決這個問題?還是有解決方法?

謝謝!

+2

你在哪裏檢查你的測試結果?你爲什麼要調用這個方法(或者爲什麼它返回一個整數),因爲你沒有對結果做任何事情? –

+0

@JBNizet代碼示例是真實業務邏輯的高度抽象。在真實的業務邏輯中,'aDependency.doSomething()'將向一個遠程服務發出http請求。根據這個遠程調用的結果,一些重要的日誌將被打印到離線分析日誌文件中,我的測試用例將驗證這些日誌條目。 – simomo

+0

問題是,你已經刪除了很多你的代碼(生產和測試),它不再有意義了。發佈一個完整的重現問題的最小例子。 –

回答

0

您是否認爲您的測試實際上可能比您的Runnable運行得更快?要求執行程序服務運行Runnable代碼,並將在單獨的線程(從ThreadPool中獲取)中執行該代碼。同時,你的測試課繼續在主線上。您可能需要查看https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CountDownLatch.html,這將允許您暫停測試代碼,直到您的業務代碼在您的鎖存器中計數完畢。請注意,您正在修改您的業務代碼以適應測試。單元測試多線程代碼是不容易的...