В классе, который я тестирую, есть несколько участников с автоматическим подключением, но один из них вызывает у меня проблему. На элемент с автосвязью ссылается интерфейс, а реализация не имеет конструктора по умолчанию. Единственный конструктор имеет аргумент с именем spring bean. Я деконструировал тестируемые классы ниже вместе с тремя различными попытками тестов, которые все терпят неудачу по разным причинам. Если кто-то знает, что я делаю не так, пожалуйста, выделите.
Это свойства и зависимости из файла pom. xml. Обратите внимание, что я использую PowerMockito с EasyMock.
<properties>
<java.version>1.8</java.version>
<powermock.version>2.0.2</powermock.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-easymock</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
BaseClass. java с автоматическим элементом
package demo;
import org.springframework.beans.factory.annotation.Autowired;
public class BaseClass {
@Autowired
Sample sampleJob;
protected void runJob() {
sampleJob.execute();
}
}
Пример интерфейса. java
package demo;
public interface Sample {
public void execute();
}
Класс реализации SampleImpl. java со ссылкой на пружинный компонент
package demo;
import org.springframework.beans.factory.annotation.Qualifier;
public class SampleImpl implements Sample {
Runnable runnable = null;
public SampleImpl(@Qualifier("myJob") Runnable job) {
runnable = job;
}
@Override
public void execute() {
runnable.run();
}
}
Наконец контрольный пример джунты. Примечание. PowerMock Runner передает делегирование Spring Runner для создания MockBean. Комментарии в каждом тесте указывают на режим и линию сбоя.
package demo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.powermock.api.easymock.PowerMock.createMock;
import static org.powermock.api.easymock.PowerMock.expectNew;
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
class BaseClassTests1 {
@MockBean
@Qualifier("myJob")
Runnable mockJob;
public BaseClassTests1() {}
@Test
@PrepareForTest(BaseClass.class)
public void testSample1() throws Exception {
Sample mockSample = createMock(Sample.class);
/*
* Try no arg constructor signature fails with:
* org.powermock.reflect.exceptions.ConstructorNotFoundException:
* No constructor found in class 'demo.Sample' with parameter types: [ <none> ].
*/
expectNew(Sample.class).andReturn(mockSample);
mockSample.execute();
BaseClass bc = new BaseClass();
bc.runJob();
}
@Test
@PrepareForTest(BaseClass.class)
public void testSample2() throws Exception {
Sample mockSample = createMock(Sample.class);
/*
* Try including mock job as part of constructor signature fails with:
* org.powermock.reflect.exceptions.ConstructorNotFoundException:
* No constructor found in class 'demo.Sample' with parameter types:
* [ org.mockito.codegen.Runnable$MockitoMock$1280448795 ].
*
*/
expectNew(Sample.class, mockJob).andReturn(mockSample);
mockSample.execute();
BaseClass bc = new BaseClass();
bc.runJob();
}
@Test
@PrepareForTest(BaseClass.class)
public void testSample3() throws Exception {
SampleImpl mockSample = createMock(SampleImpl.class);
expectNew(SampleImpl.class, mockJob).andReturn(mockSample);
mockSample.execute();
BaseClass bc = new BaseClass();
/*
* Try mock of impl class but fails with :
* java.lang.NullPointerException
* at demo.BaseClass.runJob(BaseClass.java:11)
* because the mock bean mockJob did not get autowired in the BaseClass object
*/
bc.runJob();
}
}
Примечание: установка точки останова на b c .runJob () в методе testSample3 и проверка mockSample показывает исполняемый элемент как ноль. Это не то, чего я ожидал, так как в этом тесте не произошел сбой при вызове метода allowNew ().