Использование InjectMock для объекта с закрытыми статическими полями - PullRequest
0 голосов
/ 18 мая 2018

Я пишу тестовые случаи для унаследованного кода, который по какой-то причине мы не хотим менять.Код выглядит примерно так:

 public class ToBeTested{
    private static final String field1=SomeUtil.getProperty("somekey");        
    @AutoWired
    Someservice service;
 }

В моем Junit я использую powermock с mockito и сделал что-то вроде этого

public class myTestClass{
      @Mock
      SomeService service;
      @InjectMock
      ToBeTested tested;
}

Однако InjectMocks не может создать объект для ToBeTested, так какокончательные поля не предоставляются

Поэтому я реализовал @BeforeClass и смоделировал статический метод SomeUtil.Это работает, если у меня есть только один контрольный пример.Но для более чем одного теста, только один проход, и другие терпят неудачу с той же ошибкой, что

cannot instantiate @injectmocks field named you haven't provided the instance at field declaration

Я смог решить эту проблему, используя что-то, как показано ниже:

public class myTestClass{
          @Mock
          SomeService service;

          ToBeTested tested;

    @Before
    public void setup(){
        MockitoAnnotations.initMocks(this);
        mockStatic(SomeUtil.class);
        when(SomeUtil.getProperty(anyString())).thenReturn("test");
        toBeTested=new ToBeTested();    Whitebox.setInternalState(toBeTested,"someService",someService);
    }
    }

Однако я не фанат использования отражения в Junit, которое WhiteBox делает внутри.Есть ли лучший способ сделать это?

Редактировать: Добавление фрагмента кода, предложенного Ранном в комментарии

@RunWith(PowerMockRunner.class)
@PrepareForTest(SomeUtil.class)
public class myTestClass{
      @Mock
      SomeService service;
      @InjectMock
      ToBeTested tested;

    @BeforeClass
    public static void doBeforeClass(){
        mockStatic(SomeUtil.class);
        when(SomeUtil.getProperty(anyString())).thenReturn("test");
    }

    @Test
    public void test1(){
        tested.doSomethingFor1();
    }

    @Test
    public void test2(){
        tested.doSomethingFor2();
    }
}

test1 проходит нормально.для test2 я получаю исключение как

Caused by: org.mockito.exceptions.base.MockitoException: 
Cannot instantiate @InjectMocks field named 'tested' of type 'class com.xyz.ToBeTested'.
You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : null

    at org.powermock.api.extension.listener.AnnotationEnabler.injectSpiesAndInjectToSetters(AnnotationEnabler.java:72)
    at org.powermock.api.extension.listener.AnnotationEnabler.beforeTestMethod(AnnotationEnabler.java:64)
    at org.powermock.tests.utils.impl.PowerMockTestNotifierImpl.notifyBeforeTestMethod(PowerMockTestNotifierImpl.java:82)
    ... 23 more
Caused by: java.lang.NullPointerException
    at com.xyz.SomeUtil.getProperty(SomeUtil.java:42)
...