2012-03-20 54 views
4

我在使用Mockito創建測試時遇到了一些麻煩。在與Eclipse的調試,我從Restrictions.eq得到了null,我做的每一步創建一個靜態模擬到Restrictions如何使用Mockito模擬Restriction.eq()

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ RequisicaoList.class, StatusMessages.class, 
    FacesMessages.class, Restrictions.class }) 
public class RequisicaoListTest { 

... 

@SuppressWarnings("unchecked") 
public String criteriaContigencia() { 
    Criteria criteria = criarCriteria(Requisicao.class); 

    criteria.createAlias("produto", "prod");   
    criteria.add(Restrictions.eq("prod.ar",arSelecionada)); 

    if (getExemplo().getNrProtocolo() != null) 
     criteria.add(Restrictions.eq("nrProtocolo", getExemplo() 
       .getNrProtocolo())); 

    situacoesPesquisa.clear(); 
    situacoesPesquisa.add(SituacaoRequisicao.PENDENTE_PAGAMENTO); 
    situacoesPesquisa.add(SituacaoRequisicao.PENDENTE_AGENDAMENTO); 
    if (!situacoesPesquisa.isEmpty()) { 
     criteria.add(Restrictions.in("situacao", situacoesPesquisa)); 
    } 

    if (getExemplo().getResponsavel() != null && StringUtils.isNotBlank(getExemplo().getResponsavel().getCpf())) { 
      criteria = criteria.createCriteria("responsavel"); 
      criteria = criteria.add(Restrictions.eq("cpf", getExemplo().getResponsavel().getCpf())); 
    } 

    resultado = Collections.checkedList(criteria.list(),Requisicao.class); 

    return null; 
} 

我的代碼與持久層混合managedBean,我不能改變這種狀況,但我必須創建測試該項目。

這裏的問題是嘲笑

Restrictions.eq("cpf", getExemplo().getResponsavel().getCpf()) 

,因爲連我自己:

SimpleExpression simpleExpressionEq = mock(SimpleExpression.class); 
PowerMockito.mockStatic(Restrictions.class); 
when(Restrictions.eq("cpf", "00000000091")).thenReturn(simpleExpressionEq); 

然後我仍然得到來自Restriction.eqnull回報,甚至傳遞specting值。但在調試期間,如果我在表達視圖中表達這樣做的:

Restrictions.eq("cpf", "00000000091")) 

它工作正常,並返回一個嘲笑SimpleExpression

回答

1

如果

Restrictions.eq("cpf", "00000000091")) 

正確返回,那麼也許問題與getExemplo().getResponsavel().getCpf()。你確定它返回「00000000091」嗎?你沒有包含足夠的代碼來判斷這可能是否是問題,但值得研究。

另一種方法是避免嘲笑Restrictions。當我想要做這樣的事情時,我使用真正的限制類,讓它返回一個真正的標準。我寫了一個簡單的「toStringEq」匹配器,可以用來模擬或驗證Criteria對象的行爲。當然,對象的toString()值的匹配與實際相等的匹配並不相同,但由於Criterion對象使用等於等式的實例等同性,但具有相同toString()值的Criterion對象在功能上等效,我發現它對於這個用例來說非常方便。

例如,您的電話後,只要你有一個模擬對象的標準,你可以有:

verify(mockCriteria).add(argThat(toStringEq(Restrictions.eq("cpf", "0000000091")))); 

下面是簡單的匹配類:

import org.hamcrest.Description; 
import org.mockito.ArgumentMatcher; 

public class HamcrestToStringMatcher<T> extends ArgumentMatcher<T> { 

    private T toMatch; 

    public HamcrestToStringMatcher(T toMatch) { 
     this.toMatch = toMatch; 
    } 

    @Override 
    public void describeTo(Description description) { 
     description.appendText(toMatch == null ? "null" : toMatch.toString()); 
    } 

    @Override 
    public boolean matches(Object argument) { 
     return ((toMatch == null && argument == null) || (toMatch != null 
       && argument != null && toMatch.toString().equals(
       argument.toString()))); 
    } 

    public static <T> HamcrestToStringMatcher<T> toStringEq(T toMatch) { 
     return new HamcrestToStringMatcher<T>(toMatch); 
    } 

} 
+0

嘿,這是我的錯,我抱怨一些依賴,所以我改變了代碼,但無法編譯和運行舊代碼。 – LottaLava 2012-03-21 13:34:08

+0

那麼,你們都修好了嗎? – jhericks 2012-03-21 15:46:42

+0

當然,它的一切正常,感謝您的幫助。 – LottaLava 2012-03-21 17:37:48

2

我不認爲這在測試此方法時模擬Restrictions是有意義的。這個方法的目的是包裝數據訪問(Hibernate和你正在使用的任何數據庫)。因此,對這種方法的一個有用的測試將是一個確保您正確使用數據庫的測試。

因此,我不推薦寫一個單元測試,一切都被嘲笑,我會建議編寫一個集成測試。使用內存數據庫,如H2(http://h2database.com);並編寫一個測試,建立適當的數據,然後實際選擇它。那麼,你對這種方法實際上正在做它應該做的事情的信心水平將遠遠超過單元測試會給你的東西。