2016-12-27 169 views
2

我正在實現一個SchedulerService,它使用一個AgentRestClient bean從外部系統獲取一些數據。它看起來是這樣的:Spring @MockBean沒有注入黃瓜

@Service 
public class SchedulerService { 

    @Inject 
    private AgentRestClient agentRestClient; 

    public String updateStatus(String uuid) { 
    String status = agentRestClient.get(uuid); 
    ... 
    } 
    ... 
} 

爲了測試這項服務,我使用的是黃瓜,而在同一時間我試圖嘲弄的AgentRestClient使用Spring Boot的@MockBean標註的行爲,具體如下:

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... 
} 

當我嘗試運行任何黃瓜場景時,agentRestClient從不被模擬/注入。該setUp()方法失敗了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個資源,但仍沒有運氣得到它的工作:

罪魁禍首似乎是黃瓜集成到Spring中,因爲當我用普通的JUnit @Test方法,嘲笑按預期工作。

那麼你能告訴我什麼黃瓜或春天配置有我錯過或誤解?

感謝, 波格丹

+0

你設法得到它的工作?我面臨同樣的問題 –

+0

是的,請參閱下面的答案,我希望它有幫助。 –

回答

0

好了,我發現因爲我用黃瓜運行測試,而不是通過春季啓動運行它們的@MockBean註釋被忽略。 Duh ...

因此,我用替換了@MockBean,然後我手動將該模擬注入我的服務層。

所以現在我的測試是這樣的:

@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選項。

我希望這會有所幫助。

0

@MockBean不會被忽略,豆被嘲笑,但它不注射,這樣你就可以通過@Inject注入它,這正常工作對我來說:

@Inject 
@MockBean 
private AgentRestClient agentRestClient; 
+1

現在'agentRestClient'確實不爲null,但注入的值是Spring bean('AgentRestClient $$ EnhancerBySpringCGLIB'),而不是我可以開始定義模擬行爲的模擬。這會導致'org.mockito.exceptions.misusing.NotAMockException'。這是預料之中的,因爲我不用'SpringRunner'運行測試,而用黃瓜。你如何運行你的測試? –

+0

你應該有這兩個,主要黃瓜測試運行黃瓜和你的步驟應該用springRunner註釋 – 3WJ

+0

我卡在類似的情況下,模擬對象沒有被注入。服務類獲得一個真實的對象而不是@BogdanMinciu定義的模擬。任何解決方法? – Abhi