Как JUnit обнаруживает мои частные классы и методы тестирования (дубликат)

Я взял основной ответ и сделал его контейнером МОК, чтобы определить, где разделить. ( Для тех, кто действительно ищет только разделение на 3 элемента, при чтении этого сообщения при поиске ответа? )

Этот метод позволяет разделить на любой тип элемента как

public static List<List<T>> SplitOn<T>(List<T> main, Func<T, bool> splitOn)
{
    int groupIndex = 0;

    return main.Select( item => new 
                             { 
                               Group = (splitOn.Invoke(item) ? ++groupIndex : groupIndex), 
                               Value = item 
                             })
                .GroupBy( it2 => it2.Group)
                .Select(x => x.Select(v => v.Value).ToList())
                .ToList();
}

Итак, для OP код будет

var it = new List<string>()
                       { "a", "g", "e", "w", "p", "s", "q", "f", "x", "y", "i", "m", "c" };

int index = 0; 
var result = SplitOn(it, (itm) => (index++ % 3) == 0 );
119
задан Sheldon Ross 16 March 2013 в 14:16
поделиться

6 ответов

Вы можете вызвать частный метод с отражением. Изменение последнего бита опубликованного кода:

Method method = object.getClass().getDeclaredMethod(methodName);
method.setAccessible(true);
Object r = method.invoke(object);

Существует несколько предостережений. Во-первых, getDeclaredMethod найдет только метод, объявленный в текущем Class, но не унаследованный от супертипов. Итак, перейдите по иерархии конкретного класса, если это необходимо. Во-вторых, SecurityManager может предотвратить использование метода setAccessible. Таким образом, может потребоваться выполнить функцию PrivilegedAction (используя AccessController или Subject).

245
ответ дан Aggressor 21 August 2018 в 05:29
поделиться
  • 1
    когда я это делал в прошлом, я также вызвал метод.setAccessible (false) после вызова метода, но я понятия не имею, нужно это или нет. – shsteimer 19 May 2009 в 02:53
  • 2
    Нет, когда вы устанавливаете доступность, это относится только к этому экземпляру. Пока вы не позволяете этому конкретному методу выйти из своего контроля, это безопасно. – erickson 19 May 2009 в 03:58
  • 3
    @erickson У меня есть один вопрос: java 1.1 разрешает доступ к частным методам с использованием отражения api .... Я читаю по этой ссылке, что это не junit.sourceforge.net/doc/cookstour/cookstour.htm "API-интерфейс отражения JDK 1.1 позволяет нам находить общедоступные методы & quot; – Anil Sharma 4 April 2013 в 11:30
  • 4
    Итак, каков смысл иметь частные методы, если они могут быть вызваны извне класса? – Peter Ajtai 19 September 2013 в 23:56
  • 5
    Также убедитесь, что вы вызываете getDeclaredMethod() вместо просто getMethod() - это не будет работать для частных методов. – Ercksen 14 December 2015 в 21:32

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

public static Object genericInvokMethod(Object obj, String methodName,
            int paramCount, Object... params) {
        Method method;
        Object requiredObj = null;
        Object[] parameters = new Object[paramCount];
        Class<?>[] classArray = new Class<?>[paramCount];
        for (int i = 0; i < paramCount; i++) {
            parameters[i] = params[i];
            classArray[i] = params[i].getClass();
        }
        try {
            method = obj.getClass().getDeclaredMethod(methodName, classArray);
            method.setAccessible(true);
            requiredObj = method.invoke(obj, params);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        return requiredObj;
    }

Принятые параметры: obj, methodName, количество параметров принятых и параметров. Например,

public class Test {
private String concatString(String a, String b) {
    return (a+b);
}
}

Метод concatString может быть вызван как

Test t = new Test();
    String str = (String) genericInvokMethod(t, "concatString", 2, "Hello", "Mr.x");
22
ответ дан Baby Groot 21 August 2018 в 05:29
поделиться
  • 1
    Почему нужен paramCount ? Не можете ли вы просто использовать params.length ? – Saad Malik 22 April 2014 в 05:01
  • 2
    И почему есть дополнительный массив parameters, с которым вы ничего не делаете? – Paul Samsotha 10 August 2018 в 18:33

вы можете сделать это, используя ReflectionTestUtils of Sring (org.springframework.test.util.ReflectionTestUtils)

ReflectionTestUtils.invokeMethod(instantiatedObject,"methodName",argument);

Пример: если у вас есть класс с приватным методом "square (int x)"

Calculator calculator = new Calculator();
ReflectionTestUtils.invokeMethod(calculator,"square",10);
0
ответ дан KaderLAB 21 August 2018 в 05:29
поделиться

Используйте getDeclaredMethod(), чтобы получить частный объект Method, а затем используйте method.setAccessible(), чтобы разрешить его на самом деле.

33
ответ дан Mihai Toader 21 August 2018 в 05:29
поделиться

Еще один вариант - использование очень мощной библиотеки JOOR https://github.com/jOOQ/jOOR

MyObject myObject = new MyObject()
on(myObject).get("privateField");  

Позволяет изменять любые поля, такие как конечные статические константы и вызывать защищенные методы без указания конкретного класса в иерархии наследования

<!-- https://mvnrepository.com/artifact/org.jooq/joor-java-8 -->
<dependency>
     <groupId>org.jooq</groupId>
     <artifactId>joor-java-8</artifactId>
     <version>0.9.7</version>
</dependency>
1
ответ дан Pavel Chertalev 21 August 2018 в 05:29
поделиться
  • 1
    Нет абсолютно никакого смысла отвечать на 9-летний вопрос с более чем 90000 просмотров и принятым ответом. Вместо этого ответьте на неотвеченные вопросы. – Anuraag Baishya 5 April 2018 в 10:49
2
ответ дан Pavel Chertalev 1 November 2018 в 00:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: