2014-05-06 2 views
0

Мое применение FastScanner (на основе BufferedReader) для чтения ввода (Посмотрите на раздел кода моего вопроса).JMockit: howto invoke custom method of MockUp

Если я хочу заменить ввод в своих тестах, я должен сделать макет FastScanner (Посмотрите на раздел кода моего вопроса).

Задача:For each input I should make separate mockup. Это будет greate, если я могу переключать входной сигнал внутри одного Mock Up.

Вопрос:How to add custom methods to JMockit MockUps and than call them? (Посмотрите switchInput метод FastScanner макете)

Код: [Этот раздел является обязательным, только для лучшего понимания]

FastScanner

protected static class FastScanner { 
    BufferedReader br; 
    StringTokenizer st; 

    FastScanner(InputStream f) { 
     br = new BufferedReader(new InputStreamReader(f)); 
    } 

    String next() throws IOException { 
     while (st == null || !st.hasMoreTokens()) { 
      st = new StringTokenizer(br.readLine()); 
     } 
     return st.nextToken(); 
    } 

    int nextInt() throws IOException { 
     return Integer.parseInt(next()); 
    } 
} 

FastScanner макете:

new MockUp<FastScanner>() { 

     private int[] input1 = new int[] {17, 2, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1}; 
     private int[] input2 = new int[] {5, 2, 2, 3, 3, 3, 3, 3}; 
     private int[] input3 = new int[] {8, 2, 5, 1, 3, 1, 1, 1, 1, 3, 1}; 
     private byte toggler = 1; 
     private byte pointer = 0; 

     //HERE THE QUESTION: HOW CAN I CALL THIS METHOD 
     public void switchInput() { 
      toggler++; 
      pointer = 0; 
     } 

     @SuppressWarnings("unused") 
     int nextInt() throws IOException { 
      int[] input = null; 
      switch (toggler) { 
       case 1: input = input1; break; 
       case 2: input = input2; break; 
       case 3: input = input3; break; 
      } 
      return input[pointer++]; 
     } 
    }; 
+0

Вы попробовали? Каков был результат? – Andy

+0

@ Энди, как я могу попробовать? Я не могу ставить статичность 'switchInput' и не входит в API FastScanner. Так что Java просто не видит этот метод во время компиляции –

+0

О, вы хотите вызвать '' switchInput() '' извне макета. Хм, зачем вообще это делать? почему бы не создать 3 разных макета? – Andy

ответ

1

Вы не можете иметь несколько экземпляров одного и того же MockUp подкласса одновременно (каждый такой макет будет просто отменить предыдущий, когда он получил экземпляр). Вместо этого добавьте параметр Invocation в свой метод @Mock, а затем используйте информацию, которую он предоставляет, чтобы различать несколько наборов данных. Например:

@Test 
public void testClientWithVariedDataFromFastScanners() 
{ 
    new MockUp<FastScanner>() { 
     // some data structure for test data 

     @Mock 
     int nextInt(Invocation inv) { 
      int idx = inv.getInvocationIndex(); 
      FastScanner fs = inv.getInvokedInstance(); 

      // Find the next value by using idx or fs as a lookup index 
      // into the data structures: 
      int i = ... 

      return i; 
     } 
    }; 

    client.doSomethingUsingFastScanners(); 
} 

Кроме того, если вы хотите вызвать любые методы (в том числе static методов) на макетный подкласс, просто сделать ее назвало классом, а не аноним.

+0

1) Проблема 'Invocation' заключается в том, что при компиляции я не знаю, когда переключать вход (после чего количество' nextInt' invocation). 2) Я написал 'MockUp scannerMockUp = new MockUp ()', но я до сих пор не могу вызывать пользовательские методы! Где ошибка? –

+1

Ошибка в том, что вы все еще используете класс * anonymous * mock-up. Вместо этого создайте класс * named * mock-up (т. Е. Обычный класс, который расширяет 'MockUp' и имеет имя). –

0

Возможно, это решение хуже, чем у Rogerio, но мы можем использовать внешние классы со статическими полями. Я имею в виду:

new MockUp<PrisonTransfer.FastScanner>() { 

     private int[] input1 = new int[] {17, 2, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1}; 
     private int[] input2 = new int[] {5, 2, 2, 3, 3, 3, 3, 3}; 
     private int[] input3 = new int[] {8, 2, 5, 1, 3, 1, 1, 1, 1, 3, 1}; 
     private int[] input4 = new int[] {4, 3, 3, 2, 3, 1, 1}; 
     private int[] input5 = new int[] {1, 1, 1, 2}; 
     private int[] input6 = new int[] {11, 4, 2, 2, 2, 0, 7, 3, 2, 2, 4, 9, 1, 4}; 

     @SuppressWarnings("unused") 
     @Mock 
     int nextInt() throws IOException { 
      int[] input = null; 
      switch (InputCounter.inputNumber) { //THE WHOLE POINT HERE! 
       case 1: input = input1; break; 
       case 2: input = input2; break; 
       case 3: input = input3; break; 
       case 4: input = input4; break; 
       case 5: input = input5; break; 
       case 6: input = input6; break; 
      } 
      return input[InputCounter.pointer++]; 
     } 
    }; 

    private static class InputCounter { 
     public static byte inputNumber = 1; 
     public static byte pointer = 0; 

     public void switchInput(int number) { 
      this.inputNumber = i; 
      this.pointer = 0; 
     } 
    }