【问题标题】:Mockito rule not being applied未应用 Mockito 规则
【发布时间】:2015-05-01 20:24:06
【问题描述】:

我正在使用 Mockito 编写一个测试用例,在我看来,一个 Mockito 规则没有得到定义。下面是我的场景。

public class DummyTest {
   private final String[] alphabet= {"a", "b", "c", "d", "e" };
   private final String[] numeric= {"1", "2", "3", "4", "5" };
   AtomicInteger idx;
   String currentAlphabet;
   String currentNumeric;
   int currentIndex;
   Dummy dummyObj;

   private ruleSetUp() {

       dummyObj = Mockito.spy(new Dummy());
        // Rule for rs.next()
         Mockito.doAnswer(new Answer<Boolean>() {

        @Override
        public Boolean answer(InvocationOnMock invocation) throws Throwable {
            currentIndex = idx.getAndIncrement();
            if (alphabet.length > currentIndex) {
                currentAlphabet= alphabet[currentIndex];
                currentNumeric= numeric[currentIndex];
                return true;
            } else
                return false;
        };
    }).when(rs).next();

   // Rule for rs.getInt()
   Mockito.doAnswer(new Answer<Integer>() {

        @Override
        public Integer answer(InvocationOnMock invocation) throws Throwable {
            return idx.get() - 1;
        };
    }).when(rs).getInt(2);

    // Rule for rs.getByte()
    Mockito.doAnswer(new Answer<byte[]>() {

        @Override
        public byte[] answer(InvocationOnMock invocation) throws Throwable {
            return currentNumeric.getBytes(StandardCharsets.UTF_8);
        };
    }).when(rs).getBytes(1);

       Mockito.doReturn(currentAplhabet).when(dummyObj).innerMethod(Mockito.anyInt(), Mockito.anyInt());
  }

  @Test
  public void methodTest(){


       ruleSetUp();

  }
}

我正在测试的方法如下:

class Dummy {

       public void method(int param1) {

          /*   some code  */
          param2 = xyz() ;  // Some mathematical calculation
          while(rs.next()) {

              byte[] strByte = rs.getBytes(1); 
              int number = rs.getInt(2);

              String str= new String(strByte, StandardCharset.UTF-8);
              // TEst Case rule causes below value to be always null
              String alphabet = innerMethod(param1, param2);               
          }

       }
}

在执行此测试方法时,被测试方法中的字母表值始终为空。 'str' 的值根据 currentNumeric 的正确值正确填充。循环也会运行正确的次数。

我很困惑为什么不应用 innerMethd() 的规则。我没有收到任何错误,只是填充的值始终为空,无论循环正在经历哪个迭代。

请大家指出我哪里出了问题以及解决问题的方法吗?

谢谢

【问题讨论】:

    标签: java unit-testing junit mocking mockito


    【解决方案1】:
     String currentAlphabet;
    
     private ruleSetUp() {
       // [snip]
       Mockito.doReturn(currentAlphabet).when(dummyObj).innerMethod(
           Mockito.anyInt(), Mockito.anyInt());
     }
    

    Mockito 每次调用 innerMethod 时都会返回 null因为你告诉它。尽管您在每次调用 next 时设置了 currentAlphabet,但在此之前您不会设置任何内容。在调用 ruleSetup 时,currentAlphabet 为空,因此 Mockito 为每次调用 innerMethod 存根 null

    您需要使用 answer 存根 doReturn,而不是:

    doAnswer(new Answer<String>() {
      @Override public void answer(InvocationOnMock invocation) {
        // This field on the test changes based on other invocations.
        return currentAlphabet;
      }
    }).when(dummyObj).innerMethod(anyInt(), anyInt());
    

    附带说明,因为您要替换多个相关方法的行为,所以为了可读性和易于维护,请考虑使用普通覆盖:

    private DummyObj createDummy() {
      return new DummyObj() {
        private final String[] alphabet= {"a", "b", "c", "d", "e" };
        private final String[] numeric= {"1", "2", "3", "4", "5" };
        AtomicInteger idx;
        String currentAlphabet;
        String currentNumeric;
        int currentIndex;
    
        @Override public boolean next() { /* ... */ }
        @Override public int nextInt() { /* ... */ }
        @Override public byte nextByte() { /* ... */ }
        @Override public String innerMethod() { /* ... */ }
      };
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-14
      • 1970-01-01
      • 2018-10-24
      • 2013-02-20
      • 2010-10-22
      • 1970-01-01
      相关资源
      最近更新 更多