Spring @MockBean not injected with Cucumber(Spring @MockBean 没有注入 Cucumber)
问题描述
我正在实现一个 SchedulerService,它使用 AgentRestClient bean 从外部系统获取一些数据.它看起来像这样:
I'm implementing a SchedulerService that uses a AgentRestClient bean to get some data from an external system. It looks something like this:
@Service
public class SchedulerService {
  @Inject
  private AgentRestClient agentRestClient;
  public String updateStatus(String uuid) {
    String status = agentRestClient.get(uuid);
    ...
  }
  ...
}
为了测试这个服务,我正在使用 Cucumber,同时我正在尝试使用 Spring Boot 的 @MockBean 注释来模拟 AgentRestClient 的行为,如如下:
To test this service, I'm using Cucumber while at the same time I'm trying to mock the behavior of AgentRestClient using Spring Boot's @MockBean annotation, as follows:
import cucumber.api.CucumberOptions;
import cucumber.api.java.Before;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = CentralApp.class)
@CucumberOptions(glue = {"com.company.project.cucumber.stepdefs", "cucumber.api.spring"})
public class RefreshActiveJobsStepDefs {
  @MockBean
  private AgentRestClient agentRestClient;
  @Inject
  private SchedulerService schedulerService;
  @Before
  public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
    given(agentRestClient.get(anyString())).willReturn("FINISHED");//agentRestClient is always null here
  }
  //Skipping the actual Given-When-Then Cucumber steps...
}
当我尝试运行任何 Cucumber 场景时,agentRestClient 永远不会被模拟/注入.setUp() 方法因 NPE 失败:
When I try to run any Cucumber scenario, the agentRestClient is never mocked/injected. The setUp() method fails with a NPE:
java.lang.NullPointerException
  at com.company.project.cucumber.stepdefs.scheduler.RefreshActiveJobsStepDefs.setUp(RefreshActiveJobsStepDefs.java:38)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at cucumber.runtime.Utils$1.call(Utils.java:37)
  at cucumber.runtime.Timeout.timeout(Timeout.java:13)
  at cucumber.runtime.Utils.invoke(Utils.java:31)
  at cucumber.runtime.java.JavaHookDefinition.execute(JavaHookDefinition.java:60)
  at cucumber.runtime.Runtime.runHookIfTagsMatch(Runtime.java:223)
  at cucumber.runtime.Runtime.runHooks(Runtime.java:211)
  at cucumber.runtime.Runtime.runBeforeHooks(Runtime.java:201)
  at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:40)
  at cucumber.runtime.model.CucumberFeature.run(CucumberFeature.java:165)
  at cucumber.runtime.Runtime.run(Runtime.java:121)
  at cucumber.api.cli.Main.run(Main.java:36)
  at cucumber.api.cli.Main.main(Main.java:18)
为了达到这一点,我遵循了以下 2 个资源,但仍然没有成功:
To get to this point I followed the following 2 resources, but still no luck getting it working:
- https://spring.io/blog/2016/04/15/testing-improvements-in-spring-boot-1-4
 - http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/mock/mockito/MockBean.html
 
罪魁祸首似乎是将 Cucumber 集成到 Spring 中,因为当我使用普通的 JUnit @Test 方法尝试相同的方法时,模拟按预期工作.
The culprit seems to be Cucumber integration into Spring, because when I try the same approach with a plain JUnit @Test method, mocking works as expected.
那么您能否告诉我我错过或误解了哪些 Cucumber 或 Spring 配置?
So could you please tell me what Cucumber or Spring configuration have I missed or misunderstood?
谢谢,波格丹
推荐答案
好的,所以我发现 @MockBean 注释被忽略了,因为我是用 Cucumber 运行测试而不是运行它们弹簧靴.呃……
OK, so I found out that the @MockBean annotation is ignored because I was running the tests with Cucumber instead of running them through Spring Boot. Duh...
所以我将 @MockBean 替换为 @Mock,然后我手动将该模拟注入到我的服务层中.
So I replaced @MockBean with @Mock, and then I manually inject that mock into my service layer.
所以现在我的测试看起来像这样:
So now my test looks like this:
@SpringBootTest(classes = CentralApp.class)
@ContextConfiguration
public class RefreshActiveJobsStepDefs {
  @Inject
  private SchedulerService schedulerService;
  @Mock
  private AgentRestClient agentRestClient;
  @Before
  public void setup() throws Exception {
   MockitoAnnotations.initMocks(this);
   given(agentRestClient.get(anyString())).willReturn("FINISHED");
   schedulerService.setAgentRestClient(agentRestClient);
  }
  //Skipping the actual Given-When-Then Cucumber steps...
}
如您所见,我还删除了 @CucumberOptions(glue=...) 注释,现在我确保将它传递给运行器,这对于 CLI 将使用--glue 选项.
As you can see I've also removed the @CucumberOptions(glue=...) annotation, and now I make sure to pass it though the runner, which for CLI would be by using the --glue option.
我希望这会有所帮助.
这篇关于Spring @MockBean 没有注入 Cucumber的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Spring @MockBean 没有注入 Cucumber
				
        
 
            
        - 将 Java Swing 桌面应用程序国际化的最佳实践是什么? 2022-01-01
 - 如何指定 CORS 的响应标头? 2022-01-01
 - 未找到/usr/local/lib 中的库 2022-01-01
 - Eclipse 的最佳 XML 编辑器 2022-01-01
 - 获取数字的最后一位 2022-01-01
 - GC_FOR_ALLOC 是否更“严重"?在调查内存使用情况时? 2022-01-01
 - java.lang.IllegalStateException:Bean 名称“类别"的 BindingResult 和普通目标对象都不能用作请求属性 2022-01-01
 - 如何使 JFrame 背景和 JPanel 透明且仅显示图像 2022-01-01
 - 转换 ldap 日期 2022-01-01
 - 在 Java 中,如何将 String 转换为 char 或将 char 转换 2022-01-01
 
						
						
						
						
						
				
				
				
				