【问题标题】:How to mock Restriction.eq( ) using Mockito如何使用 Mockito 模拟 Restriction.eq()
【发布时间】:2012-04-05 01:45:53
【问题描述】:

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

@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.eq 获得null 返回,即使传递了规范值。但是在调试过程中,如果我在表达式视图中做一个表达式:

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

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

【问题讨论】:

    标签: java hibernate unit-testing mockito powermock


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      如果

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

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

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

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

      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);
          }
      
      }
      

      【讨论】:

      • 嘿,这是我的错,我抱怨某些依赖项,所以我正在更改代码但无法编译和运行旧代码。
      猜你喜欢
      • 2016-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多