Есть ли способ с помощью Mockito
или PowerMockito
перехватывать вызовы нестатических c методов объекта или хотя бы одноэлементного объекта?
Приведен пример следующими классами:
public class Singleton {
private static Singleton INSTANCE = null;
private Singleton(Object parameter) {}
public static Singleton getInstance(Object parameter) {
if (INSTANCE == null) {
INSTANCE = new Singleton(parameter);
}
return INSTANCE;
}
public String process(String a, String b) {
return (a + b);
}
// Other methods
}
public class Foreign {
private Foreign() {}
public static void main(String[] args) {
System.out.println(Singleton.getInstance(new Object()).process("alpha", "beta"));
}
}
Объект Singleton
создается в классе Foreign
вне контроля некоторого тестового кода (не показан выше). Ни один из этих двух классов не может быть изменен. Цель состоит в том, чтобы перехватить вызовы нестатического c process()
метода в тестовом коде, чтобы для определенных значений возвращался другой результат, например вызов
Singleton.getInstance(new Object()).process("alpha", "beta");
имитируемый для возврата "alpha-beta"
вместо ожидаемого "alphabeta"
.
Одним из решений может быть перехват метода Singleton.getInstance()
для создания экземпляра настраиваемого подкласса Singleton, например, с использованием
public class SubSingleton extends Singleton {
public SubSingleton(Object parameter) {
super(parameter);
}
public String process(String a, String b) {
if ("alpha".equals(a) && "beta".equals(b)) {
return a + "-" + b;
}
return super.process(a + b);
}
}
Затем вызывает к методу Singleton.process()
будет перехвачен, как в:
Object parameter = new Object();
PowerMockito.doReturn(new SubSingleton(parameter)).when(Singleton.class, "getInstance", parameter);
Однако приведенный выше класс Singleton
предоставляет только частный конструктор, поэтому его нельзя расширить. Использование PowerMockito.whenNew()
для возврата частичного имитации (шпиона) также не будет работать, поскольку класс Singleton
не предоставляет конструктор без аргументов.
Можно ли реализовать желаемый имитатор каким-либо другим способом? Можно ли это сделать для не-одиночных классов?