PowerMockito whenNew не работает с несколькими конструкторами

whenNew не работает, если у меня есть два конструктора - один без аргументов и один с аргументами. В фрагменте кода ниже мне нужно, чтобы реальный конструктор вызывался во второй раз, но вместо этого я получаю NullPointerException.

 @RunWith(PowerMockRunner.class)
    public class UtilTest {

        @Test
        public void test()throws Exception {
            A a= new A();
            a.setI(10);
            whenNew(A.class).withNoArguments().thenReturn(a);

            UtilTest test= new UtilTest();
            test.testA();

        }

        private void testA(){
            A a1= new A();
            System.out.println(a1.getI());
            A a2= new A(50);
            System.out.println(a2.getI());
        } 
    }

    class A{
        int i=1;
        public A(){}

        public A(int i){
            this.i=i;
        }

        public void setI(int i){
           this.i=i;
        }

        public int getI(){
            return this.i;
        }
    }

Вывод —

10
java.lang.NullPointerException

person shashankaholic    schedule 05.10.2015    source источник
comment
1) Если я не добавлю @PrepareForTest(UtilTest.class), он будет успешно печатать 10 и 50. 2) Если вам не важно, какой конструктор вызывается, используйте whenNew(A.class).withAnyArguments().thenReturn(a);. 3) Если вы заботитесь о конструкторе, то определите значения для каждого из них, а затем 4) В противном случае дайте нам некоторый контекст, потому что это немного странно понимать, почему и что вам нужно.   -  person Morfic    schedule 06.10.2015
comment
Извините, @Morfic, если я недостаточно ясно выразился. Мой ожидаемый результат - 10 и 50. 1) - это даст 1 и 50 2) и 3) мне не все равно, над каким конструктором издеваться. 4) Моя цель издеваться над конструктором без аргументов, но не с другим. Своего рода частичный макет создания объекта, не знаю, возможно ли это.   -  person shashankaholic    schedule 06.10.2015
comment
Не уверен, что это возможно, но если я не ошибаюсь, вы должны иметь возможность издеваться над своим A и возвращать 10, а затем 50 для getI(). Что-то вроде: A mockA = mock(A.class); when(mockA.getI()).thenReturn(10, 50); whenNew(A.class).withAnyArguments().thenReturn(mockA);. Не забудьте @PrepareForTest(UtilTest.class)   -  person Morfic    schedule 06.10.2015


Ответы (1)


(1) Сохраняйте метод класса newInstance(int) перед манипуляциями с классом

(2) Попробуйте определить оба конструктора.

whenNew(A.class)
    .withNoArguments()
    .thenReturn(a);
whenNew(A.class)
    .withArguments(...)
    .doAnswer(call original constructor);
person ursa    schedule 05.10.2015
comment
Последний шанс: приватные конструкторы + статические фабричные методы - person ursa; 06.10.2015
comment
Спасибо Урса за оперативные ответы. К сожалению, doAnswer перейдет в stackoverflow, так как снова вызовет whennew, и это будет продолжаться. И я ничего не могу сделать с классом А, потому что он из банки. - person shashankaholic; 06.10.2015
comment
Если вы сохраните ссылку на исходный метод class.newInstance(int) и вызовете его из ответа - получить stackoverflow будет невозможно. Я что-то пропустил? - person ursa; 06.10.2015