我有一个spring项目,并且我正在使用Gradle,所以我用一些@Test创建了此接口,我想将其重用于测试其他类
import static org.junit.Assert.assertEquals;
import java.util.List;
import java.util.Optional;
import javax.persistence.Entity;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.data.jpa.repository.JpaRepository;
public interface CrudTest<T> {
public JpaRepository<T, Long> getRepository();
public Crud<T> getService();
public T getEntity();
public List<T> getEntities();
public default void asserts(T entity) {
assertEquals(getEntity(), entity);
}
public default void asserts(List<T> entities) {
List<T> idealEntities = getEntities();
for (int i = 0; i < idealEntities.size(); i++) {
assertEquals(idealEntities.get(i), entities.get(i));
}
}
public default void setUp() {
Mockito.when(getRepository().findAll()).thenReturn(getEntities());
// Mocking others methods
....
}
@Test
public default void create() {
T entity = getService().create(getEntity());
asserts(entity);
}
@Test
public default void update() {
T entity = getService().update(getEntity());
asserts(entity);
}
@Test
public default void retrieveOne() {
T entity = getService().retrieve(1L);
asserts(entity);
}
@Test
public default void retrieveAll() {
List<T> entities = getService().retrieve();
asserts(entities);
}
}
我正在这样实现此接口:
import java.util.ArrayList;
import java.util.List;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.jpa.repository.JpaRepository;
@RunWith(MockitoJUnitRunner.class)
public class CountryServiceTest implements CrudTest<Country> {
@InjectMocks
private CountryService countryService;
@Mock
private CountryRepository countryRepository;
@Override
public JpaRepository<Country, Long> getRepository() {
return countryRepository;
}
@Override
public Crud<Country> getService() {
return countryService;
}
@Override
public Country getEntity() {
Country country = new Country(1L, "UUEE");
return country;
}
@Override
public List<Country> getEntities() {
List<Country> countries = new ArrayList<>();
Country country = new Country(1L, "UUEE");
countries.add(country);
country = new Country(2L, "Canada");
countries.add(country);
return countries;
}
}
像这样
import java.util.ArrayList;
import java.util.List;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.jpa.repository.JpaRepository;
@RunWith(MockitoJUnitRunner.class)
public class CityServiceTest implements CrudTest<City> {
@InjectMocks
private CityService cityService;
@Mock
private CityRepository cityRepository;
@Override
public JpaRepository<City, Long> getRepository() {
return cityRepository;
}
@Override
public Crud<City> getService() {
return cityService;
}
@Override
public City getEntity() {
City city = new City(1L, "New York", new Department());
return city;
}
@Override
public List<City> getEntities() {
List<City> cities = new ArrayList<>();
City city = new City(1L, "New York", new Department());
cities.add(city);
city = new City(2L, "Boston", new Department());
cities.add(city);
return cities;
}
}
如您所见,我想测试几个@Service来创建,检索,更新和删除(CRUD)。但这基本上是相同的,我的意思是模拟存储库以测试创建,检索和所有这些东西的方法,因此这就是原因,因为我想创建一个接口并将相同的东西放在那里。但是我遇到了一个错误,因为在我的类CityServiceTest和CountryServiceTest中,我没有带@Test批注的方法。我得到的错误是这样的:
java.lang.Exception: No runnable methods
at org.junit.runners.BlockJUnit4ClassRunner.validateInstanceMethods(BlockJUnit4ClassRunner.java:191)
at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:128)
at org.junit.runners.ParentRunner.validate(ParentRunner.java:416)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:84)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:65)
at org.mockito.internal.runners.DefaultInternalRunner$1.<init>(DefaultInternalRunner.java:28)
at org.mockito.internal.runners.DefaultInternalRunner.<init>(DefaultInternalRunner.java:28)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at org.mockito.internal.runners.util.RunnerProvider.newInstance(RunnerProvider.java:27)
at org.mockito.internal.runners.RunnerFactory.create(RunnerFactory.java:69)
at org.mockito.internal.runners.RunnerFactory.createStrict(RunnerFactory.java:40)
at org.mockito.junit.MockitoJUnitRunner.<init>(MockitoJUnitRunner.java:154)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:78)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:66)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:118)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:175)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:157)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
at java.base/java.lang.Thread.run(Thread.java:834)
因此,我想知道是否可以使用接口,或者是否必须在每个特定的类中重复测试。非常感谢您的建议,
答案 0 :(得分:0)
@Test没有标记为@Inherited,因此您的实现类将不包含任何带有@Test注释的方法。
应该可以创建自己的继承自测试的注释:
@Inherited
@Test
@Retention(value=RUNTIME)
@Target(value=METHOD)
public @interface AbstractTest