如何用mockito+spring進行單元測試(2)


以前寫過一篇blog,寫得不是很詳細。這次清明節在家好好的整理了下思路,把相關的細節重寫下來。很奇怪這些內容在google上找不到,也許是太基本了吧。

為了理解mockito,必須先明白mock測試的原理,它分成以下幾個步驟:

建立mock;
將mock和待測試的對象連接起來;
在mock上設置預期的返回值;
開啟replay模式,准備記錄實際發生的調用;
進行測試;
驗證測試結果,調用順序是否正確,返回值是否符合期望;

本文主要講第一步和第二步。

對於Mockito而言,有兩種方式創建:

  • 1. mock為一個interface提供一個虛擬的實現,
  • 2. spy為object加一個動態代理,實現部分方法的虛擬化。

假設待測試的class聲明如下:

public class Svc{

    DaoInterface dao1;

    DaoInstance dao2;

   …

你可以用如下的聲明得到一個Interface的mock,或者一個實例的spy,並把它注入到測試對象中:

private Svc svc;
private DaoInterface mockdao;

@Before

public void setup(){

mockdao = mock(DaoInterface.class);
svc.setDao1(mockdao);

}


private Svc svc;
private DaoInstance spydao ;

@Before

public void setup(){

tmp= new DaoInstance ();

spydao = spy(tmp);
svc.setDao2(spydao);

}

 

請注意到spy和mock的不同。但是spy並不是很好的實踐,因為它意味着你的代碼不能很好的將變化的部分分離開來。因此最好只在那些歷史遺留系統上使用。

上面這種方式並不唯一的途徑。為了避免重復代碼,Mockito提供了幾個注解:

@Mock,被標注的屬性是個mock

@Spy,被標注的屬性是個spy,需要賦予一個instance

@InjectMocks,將本test中的mock或者spy注入到被標注的屬性中,根據構造函數的參數名,或者setter,或者私有屬性名。

最后在setup中調用MockitoAnnotations.initMocks(this);就免去了代碼的編寫。如下所示:

private @InjectMocks Svc svc;
private @Mock DaoInterface dao1;

@Before

public void setup(){

//mockdao = mock(DaoInterface.class);
//svc.setDao1(mockdao);

MockitoAnnotations.initMocks(this);

}


private @InjectMocks Svc svc;
private @Spy DaoInstance dao2=new

DaoInstance() ;

@Before

public void setup(){

// tmp= new DaoInstance ();

// spydao = spy(tmp);
// svc.setDao2(spydao);

MockitoAnnotations.initMocks(this);

}

如果你使用spring,上述代碼還可以進一步簡化,因為Mockito提供了factory的方法用來創建mock和spy。

正常的bean聲明 <bean id=”svc” class=”Svc”>
<bean id=”dao1” class=”…”>
<bean id=”dao2” class=”…”>
mock

<bean id="dao1"  class="org.mockito.Mockito" factory-method="mock">
           <constructor-arg value="DaoInterface"></constructor-arg>
</bean>

請注意到svc不變化,mock將自動注入進入。這是因為spring的bean容器,如果id一樣,后聲明的bean會覆蓋前面的bean。

spy

<bean id="daoInst"  class="DaoInstance">
</bean>
<bean id="dao2"  class="org.mockito.Mockito" factory-method="spy">
       <constructor-arg ref="daoInst"></constructor-arg>
</bean>

同樣svc不變化,直接注入。請注意spy需要獲得一個實例。

然后你只需要對dao1和dao2進行方法設置就可以了。

Technorati Tags: mockito, spring, mock, spy


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM