Как мне создать интерфейс для повторного использования некоторых тестов? - PullRequest
0 голосов
/ 15 января 2019

У меня есть весенний проект, и я использую 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)

Так что я хочу знать, возможно ли использовать интерфейс или мне обязательно нужно повторять тесты в каждом конкретном классе. Я действительно ценю некоторые предложения по этому поводу, заранее спасибо

1 Ответ

0 голосов
/ 15 января 2019

@ Test не помечен @Inherited, поэтому ваш реализующий класс не будет содержать методов, помеченных @ Test.

Должно быть возможно создать собственную аннотацию тестирования, которая наследуется следующим образом:

@Inherited
@Test
@Retention(value=RUNTIME)
@Target(value=METHOD)
public @interface AbstractTest
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...