Тестирование @Mockbean. NPE при вызове бина из контекста

Здравствуйте дорогие коллеги! Ситуация:

  • -Spring Boot проект;
  • -сборщик Gradle;

на всякий случай проект на GitHub:этот проект на гите вот тест:

package kondratov.spring_feign.feign;

import org.junit.Assert;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.ApplicationContext;

import static org.mockito.Mockito.mock;

//@RunWith(SpringRunner.class) - это предлагает пример, у меня JUpiter

public class MockbeanTest {

    @MockBean
 
    GIFservice giFserviceMock = mock(GIFservice.class);

    @Autowired
    ApplicationContext context;

    @Test
    public void givenCountMethodMocked__WhenCountInvoked__ThenMockValueReturned() {
      
        //https://api.giphy.com/v1/gifs/random?api_key=YjMBpwuaouTnbKjk18LH9rM2uOrNivuk&tag=rich&rating=g
        Mockito.when(giFserviceMock.getData("YjMBpwuaouTnbKjk18LH9rM2uOrNivuk", "rich", "g")).thenReturn("test");
        //собственно, вот тут ^ тоже орал NPE в методе ***when***, пока выше не объявил: 
        //`GIFservice giFserviceMock = mock(GIFservice.class);` сначала было просто:
        // `GIFservice giFserviceMock;`

        GIFservice giFservice = context.getBean(GIFservice.class);
        //вот тут говорит: find why context null
        String s = (String) giFservice.getData("YjMBpwuaouTnbKjk18LH9rM2uOrNivuk", "rich", "g");
   
        Assert.assertEquals("test", s);
      
        Mockito.verify(giFserviceMock).getData("YjMBpwuaouTnbKjk18LH9rM2uOrNivuk", "rich", "g");
    }
}

вот код GIFservice:

package kondratov.spring_feign.feign;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name = "simple-client", url = "https://api.giphy.com")
public interface GIFservice {


    @GetMapping("/v1/gifs/random")
    Object getData(@RequestParam("api_key") String apiKey,
                   @RequestParam("tag") String tag,
                   @RequestParam("rating") String rating);

}

Как я понял тут одно из двух, либо не работает вызов бина из контекста, либо его там вообще нет. В общем вопрос, создаю мок для интерфейса (Feign), что делаю не так? Как починить или вообще по-другому надо? Заранее спасибо!

PS gradle:

plugins {
    id 'org.springframework.boot' version '2.3.0.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
    id 'java'
    id 'io.freefair.lombok' version '5.0.0'
}

group = 'kondratov.spring_feign'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
    mavenCentral()
}
ext {
    set('springCloudVersion', 'Hoxton.SR5')
}
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' 
    implementation 'org.springframework.boot:spring-boot-starter-tomcat'
    implementation 'org.springframework:spring-test'
    testCompile('com.github.tomakehurst:wiremock:2.1.12')//Добавил ВиремокТест

    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}
dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}
test {
    useJUnitPlatform()
}


Ответы (1 шт):

Автор решения: Alexander Pavlov
//@RunWith(SpringRunner.class) - это предлагает пример, у меня JUpiter

Если у тебя Junit5, то надо инициализировать контекст с помощью аннотаций Junit5 (@ExtendWith(SpringExtension.class))

Вот тут есть примеры миграции с Junit4 на Junit5

https://www.baeldung.com/junit-5-runwith#migrating-from-a-junit4-based-runner


Ну и вообще стоит почитать, чтобы не лепить аннотации наугад.

    @MockBean
     GIFservice giFserviceMock = mock(GIFservice.class);

    @Autowired
    ApplicationContext context;

@MockBean означает "создать мок, поместить в контекст и заинжектить во все классы в контексте, где этот бин требуется". Отсюда следует

  1. giFserviceMock = mock(GIFservice.class); - не надо самому инициализировать

  2. GIFservice giFservice = context.getBean(GIFservice.class) - не надо самому в контексте искать, Спринг вставит значение мока в переменную, помеченную @MockBean

→ Ссылка