Есть ли способ пройти тест JUnit, если реализация метода верна и рекурсивна? - PullRequest
0 голосов
/ 20 июня 2019

Я готовлю некоторые практические экзамены и требую, чтобы определенные методы были рекурсивными.Есть ли способ пройти тест JUnit, только если реализация метода рекурсивна (и, конечно, правильна)?

Я пытался использовать getStackTrace(), но не смог найти способ получитьвызовы методов, сделанные ранее в программе.(Потому что, если я могу это сделать, я могу проверить, вызывается ли containsDigit в следующем примере необходимое количество раз)

MWP

import static org.junit.Assert.*;
import org.junit.*;
import java.io.*;
import java.text.*;
import java.util.*;
import org.junit.rules.*;
import java.lang.reflect.*;

public class Service { //begin class 
    /**
     * @param n: assumed to be more than 0
     * @param d, d >= 0 and d <= 9
     * @return true if number n contains the digit d, false otherwise
     * you may assume that 0 itself doesn't contain ANY digit (not even 0)
     * NOTE: This method must be implemented recursively.
     * hint: n%10 gives the last digit, n/10 gives the rest of the number
     */
    public static boolean containsDigit(int n, int d) {
        return false; //to be completed
    }

    @Test
    public void testContainsDigit() {
        assertTrue(Service.containsDigit(1729, 1));
        assertTrue(Service.containsDigit(1234567890, 2));
        assertFalse(Service.containsDigit(1729, 8));
    }
}

Я бы хотел, чтобы тестпройти для рекурсивной реализации, такой как:

    public static boolean containsDigit(int n, int d) {
        if(n == 0) 
            return false;
        if(n%10 == d)
            return true;
        return containsDigit(n/10, d);
    }

и потерпеть неудачу для итеративной (даже если правильной) реализации, такой как:

    public static boolean containsDigit(int n, int d) {
        while(n > 0) {
            if(n%10 == d) {
                return true;
            }
            n/=10;
        }
        return false;
    }

Любая помощь или руководство в правильном направлении будет оченьбыть оцененным.

1 Ответ

1 голос
/ 20 июня 2019

Сам JUnit не имеет инструментов для проверки того, является ли поток рекурсивным или итеративным, но он, безусловно, может проверить, что вызов возвращает правильные результаты.

Теперь также невозможно собрать трассировки стека из "более ранних" казней.

Я тоже не понимаю, чем тут могут помочь насмешки, но я могу что-то упустить, может быть, наши коллеги приведут пример для этого, однако я предлагаю следующий подход:

  • Не требуется, чтобы метод был статическим, вместо этого требуется, чтобы методы были регулярными.

Тогда используйте следующий трюк:

Подготовьте следующий класс, но не предоставляйте его студентам (я предположил, что это для образовательных целей, так как вы говорили об экзаменах, извините, если я ошибаюсь), которые, как ожидается, будут внедрять «Сервис» "класс:

 class MyServiceForChecks extends Service {
      private List<StackTraceElement[]> invocationStackTraces = new ArrayList<>(); 

      public boolean containsDigit(int n, int d) { // its not static anymore
           StackTraceElement [] stackTrace =  getStackTrace();
           invocationStackTraces.add(stackTrace); 
        return super.containsDigit(n,d);
      }

      public List<StackTraceElement[]> getInvocationStackTraces () {
           return this.invocationStackTraces;
      }
 }

В JUnit тестируйте класс MyServiceForChecks вместо класса Service. После того, как метод containsDigits завершит выполнение, вы можете вызвать метод getInvocationStackTraces и проанализировать результат.

Если вы не можете создать класс MyServiceForChecks, вы можете сгенерировать его динамически с помощью библиотеки CGLIB.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...