Макет инстанса> с пометкой Inject & Any в Junit - PullRequest
0 голосов
/ 28 мая 2018

В моем проекте javaee есть интерфейс:

public interface SomeInterface{...}

и несколько реализаций:

@Stateless(name = "ImplementationA")
public class ImplementationA implements SomeInterface{...}

@Stateless(name = "ImplementationB")
public class ImplementationB implements SomeInterface{...}

Для доступа ко всем реализациям у меня есть следующее в другомкласс:

@Singelton
public class AnotherClass{
    @Inject
    @Any
    private Instance<SomeInterface> impls;

    public SomeInterface someMethod(){
        for(SomeInterface imp : impls){
            if(imp.oneMethod()){
                return imp;
            }
        }
        return null;
    }
}

Если я хочу выполнить модульное тестирование для этого "AnotherClass", как мне высмеивать поле

Instance<SomeInterface> impls

?

Tried @Mock,@Spy, не удалось получить "имплс" должным образом смоделированным изнутри Mockito, когда тест запускается, "имплс" всегда нулевой.

Сам модульный тест выглядит следующим образом:

@RunWith(MockitoJUnitRunner.class)
public class SomeTestClass {
    @InjectMocks
    AnotherClass anotherClass;

    @Spy // Here I tried @Mock as well
    private Instance<SomeInterface> impls;

    @Test
    public void TestSomeMethod(){
        Assert.assertTrue( anotherClass.someMethod() == null ); // <- NullPointerException here, which indicates the impls is null instead of anotherClass.
    }
}

Пришлось добавить еще один метод в этот "AnotherClass" для принятия экземпляра имплантов экземпляра, который создается в модульном тесте, которыйработает, но уродливо, что другой не относящийся к делу метод должен быть добавлен только для целей модульного тестирования.

Есть идеи, как выглядит правильный способ выполнения модульного теста?

Версия Mockito и Junit:

group: 'junit', name: 'junit', version: '4.12'
group: 'org.mockito', name: 'mockito-core', version:'2.12.0'

Заранее спасибо.

1 Ответ

0 голосов
/ 29 мая 2018

Что вы можете попытаться сделать:

  1. Добавьте некоторые ожидания, если они вам нужны.Вам, вероятно, понадобится impls.xxxx(), чтобы вызвать реальный метод, если это шпион (угадайте, это поведение по умолчанию).
  2. Возможно, сначала попытайтесь инициализировать mock:

    @RunWith(MockitoJUnitRunner.class)
    public class SomeTestClass {
        @InjectMocks
        AnotherClass anotherClass;
    
        @Spy  
        private Instance<SomeInterface> impls;
    
        // init here
        @Before 
        public void initMocks() {
            MockitoAnnotations.initMocks(this);
        }
    
        @Test
        public void TestSomeMethod(){
            anotherClass.someMethod(); // <- NullPointerException here, which indicates the impls is null instead of anotherClass.
        }
    }
    

Этот вызов инициализации должен быть где-то в базовом классе или в тестовом организаторе.

Это странно, без которого он не работает, я думаю, если вы используете MockitoJUnitRunner, он должен работать.

...