首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Mockito模拟Restriction.eq( )

如何使用Mockito模拟Restriction.eq( )
EN

Stack Overflow用户
提问于 2012-03-20 23:07:57
回答 2查看 2.4K关注 0票数 4

我在用Mockito创建测试时遇到了一些麻烦。在使用Eclipse进行调试期间,我从Restrictions.eq获得了一个null,我完成了为Restrictions创建静态模拟的每一步

代码语言:javascript
复制
@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和持久层,我不能改变这一点,但我必须为该项目创建测试。

这里的问题是模拟

代码语言:javascript
复制
Restrictions.eq("cpf", getExemplo().getResponsavel().getCpf())

因为即使是我也这样做:

代码语言:javascript
复制
SimpleExpression simpleExpressionEq = mock(SimpleExpression.class);
PowerMockito.mockStatic(Restrictions.class);
when(Restrictions.eq("cpf", "00000000091")).thenReturn(simpleExpressionEq);

然后,我仍然会从Restriction.eq返回null,甚至传递侦查值。但是在调试期间,如果我在表达式视图中创建一个表达式,执行以下操作:

代码语言:javascript
复制
Restrictions.eq("cpf", "00000000091"))

它工作正常,并返回一个模拟的SimpleExpression

EN

回答 2

Stack Overflow用户

发布于 2012-03-21 14:31:30

我不认为在测试此方法时模拟Restrictions是有意义的。此方法的目的是包装数据访问(Hibernate和您正在使用的任何数据库)。因此,这种方法的一个有用的测试是确保您正确使用数据库的测试。

因此,我建议您编写一个集成测试,而不是编写一个所有东西都被模拟的单元测试。使用内存中的数据库,比如H2 (http://h2database.com);编写一个测试来设置适当的数据,然后实际选择它。然后,您对此方法实际上正在做它应该做的事情的置信度将远远超过单元测试提供给您的。

票数 2
EN

Stack Overflow用户

发布于 2012-03-21 03:48:40

如果

代码语言:javascript
复制
Restrictions.eq("cpf", "00000000091"))

是正确返回的,那么问题可能出在getExemplo().getResponsavel().getCpf()。你确定它会返回"00000000091“吗?您还没有包含足够的代码来判断这是否是问题所在,但它值得研究。

另一种方法是完全避免嘲笑Restrictions。当我想做这样的事情时,我会使用真正的限制类,并让它返回一个真正的标准。我编写了一个简单的"toStringEq“匹配器,可以用来模拟或验证Criteria对象的行为。当然,匹配对象的toString()值与匹配实际相等是不同的,但是由于Criterion对象使用实例相等来表示相等,但是具有相同toString()值的Criterion对象在功能上是等价的,我发现它对于这个用例非常方便。

例如,在调用之后,如果您有一个模拟条件对象,您可以拥有:

代码语言:javascript
复制
verify(mockCriteria).add(argThat(toStringEq(Restrictions.eq("cpf", "0000000091"))));

下面是简单的matcher类:

代码语言:javascript
复制
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);
    }

}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9789401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档