2012-03-20 94 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);并编写一个测试,建立适当的数据,然后实际选择它。那么,你对这种方法实际上正在做它应该做的事情的信心水平将远远超过单元测试会给你的东西。