2016-06-29 25 views

回答

2

就是這樣。您的測試等級:

import java.util.Random; 

public class Simple { 
    public String id1() 
    { 
     Random random=new Random(); 
     int i=random.nextInt(); 
     if(i<0) 
     { 
      i=-(i); 
     } 
     if(i<1000) 
      i=i+1000; 
     while(i>9999) 
     { 
      i=i/10; 
     } 
     return i+""; 
    } 
} 

測試(我使用powermock-mockito-1.6.2)。你應該處理生成的數字:

import java.util.Random; 

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

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ Random.class, Simple.class }) 
public class SimpleTest { 

    @Test 
    public void ifGenerateNumberLessZeroSetItMoreThanZero() throws Exception { 
     Random rand = Mockito.mock(Random.class); 
     PowerMockito.mockStatic(Random.class); 
     PowerMockito.whenNew(Random.class).withNoArguments().thenReturn(rand); 

     Mockito.when(rand.nextInt()).thenReturn(-9999); 

     Simple simple = new Simple(); 
     Assert.assertEquals("9999", simple.id1()); 
    } 
} 
+0

這就是所謂的反射? –

+2

認真:不要按照這個建議。你的問題是你創建了無法測試的代碼;並且使用PowerMock將導致更多的麻煩...比簡單地去修復**破碎的設計。 – GhostCat

+1

@DavidFindlay PowerMock是**不**使用反射。這是一個模擬框架,它只需要編譯的類文件,並修改**中的字節碼以使其可測試。這就是爲什麼PowerMock的「好用例」數量非常接近於零。 – GhostCat

3

你可以打破邏輯到它自己的方法:

public String id1(int i) 
{ 
    if(i<0) 
    { 
     i=-(i); 
    } 
    if(i<1000) 
     i=i+1000; 
    while(i>9999) 
    { 
     i=i/10; 
    } 
    return i+""; 
} 

然後改變你的只是傳遞一個隨機INT調用ID1方式:

id1(new Random().nextInt()); 

然後你可以測試邏輯。這是最簡單的,即使不是最完美的解決方案。更困難的解決方案是模擬nextInt()方法,以便控制在測試中返回的內容 - 在此可能不是必需的,但對於某些情況將是唯一方法。

0

你的問題是你創建了無法測試的代碼。

重點是:如果一個方法創建輸入它正在處理它自己...那麼就沒有測試該方法。是的,你可以使用PowerMock來控制隨機類,但這是完全錯誤的方法。 PowerMock只是沒有人應該使用的(參見here出於某些原因);如果有的話,您可以將其用於無法更改的第三方代碼。但是當我們談論自己的代碼時,最好提出可測試的設計;而不是創建一個糟糕的設計,然後轉向PowerMock以某種方式測試它。

通常,您使用依賴關係注入爲了獲得對您的方法將使用的「數據」的控制;

public String formatStringIdFrom(int id) { ... } 

如果你真的想提高你的代碼的質量,我建議你退一步一些3,5小時,觀看所有從這個谷歌的視頻:在這種情況下,這可能是簡單科技series ......相信我,這絕對值得您的光臨。

其他一些注意事項:

  • 的良好的單元測試的本質是...他們總是返回相同的結果。這意味着:基於隨機值的代碼...應該至少允許提供種子,以便您可以編寫保證總能看到相同輸入的測試用例。在每次運行中爲您提供不同結果的單元測試...很簡單:不是很有幫助。
  • id1()是一個非常沒用的名稱的方法。它不告訴你什麼什麼方法應該做
  • 考慮創建一個真正代表ID的具體類。好的設計是關於創建抽象,讓你以更有意義的方式處理事情。只是推動整數;並聲明由這樣的整數構成的任何4位數的字符串都是「id」......只是一種非常幼稚的方法。
  • 最後:你可以大大簡化4位數的生成;你只需要:int number = random.nextInt(9000) + 1000直接給你之間的值(1000,9999)。