2017-06-22 142 views
0

我試圖讓我的測試單元啓動並運行,並且遇到了一個奇怪的問題。我的應用程序使用註釋爲@Component的ApplicationListener類在啓動過程中執行操作。在測試期間在Spring Boot中排除ApplicationListener @Component

在測試過程中,我嘲笑包含邏輯的服務,但是我發現即使Mockito的指令在控制器範圍內工作良好,bean也不會初始化爲此ApplicationListener類:而不是返回我在測試中定義的內容單位,它返回false或null - 取決於服務中每個方法返回的數據類型。

因爲我還沒有找到任何方法來初始化來自ApplicationListener類的測試單元的模擬服務,所以我決定排除它。爲此,我嘗試了不同的方法,這是創建測試應用程序上下文並更改其配置最常用的方法。不幸的是,我沒有看到任何工作 - 所以我在這裏尋求幫助。如果可能的話,我寧願不要觸摸ApplicationListener類,並在測試代碼中執行所有相關的編碼。

我感興趣的任何兩個可能的解決方案,如果他們可以做到:

1.-獲取了ApplicationListener執行過程中嘲笑的行爲,但我已經在其他地方見過這個不能做

2.-以某種方式從測試單元中排除@Component。

TestUnit.Java

@RunWith(SpringRunner.class) 
@SpringBootTest(classes = TestApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) 
@AutoConfigureMockMvc 
public class TestConfigurationService { 
    private MockMvc mockMvc; 

    @Autowired 
    private WebApplicationContext webApplicationContext; 

    @MockBean 
    private MockService mockService; 

    private void initMockBean() throws Exception { 
     when(mockService.isDoingSomething()).thenReturn(true); 
    } 

    @Before 
    public void setup() throws Exception { 
     // Spring mock context application setup 
     this.mockMvc = webAppContextSetup(webApplicationContext).build(); 

     // Initialize ConsulService mock bean 
     initMockBean(); 
    } 
} 

TestApplication.java

@SpringBootApplication 
@EnableAutoConfiguration 
@ComponentScan(basePackages="my.base.package", excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = StartupConfiguration.class)) 
public class TestApplication { 
    public static void main(String[] args) {  
     SpringApplication.run(TestApplication.class, args); 
    } 
} 

而且什麼代碼所示,我也試過這個註釋文件TestApplication.java:

@SpringBootApplication(exclude={StartupConfiguration.class}) 

StartupConfiguration.java

@Component 
public class StartupConfiguration implements ApplicationListener<ContextRefreshedEvent> { 
    @Autowired 
    private ConfigurationService configurationService; 

    @Override 
    public void onApplicationEvent(final ContextRefreshedEvent event) {  
     try { 
      configurationService.updateConfiguration(); 
     } catch (Exception e) { 
      throw new RuntimeException ("Error", e); 
     } 
    } 
} 

ConfigurationService.java

public interface ConfigurationService { 
    public void updateConfiguration() throws Exception; 
} 

ConfigurationServiceImpl.java

@Service 
@Transactional 
public class ConfigurationServiceImpl implements ConfigurationService {  
    @Autowired 
    private MService mockService; 

    @Override 
    public void updateConfiguration() throws Exception {  
     if (mockService.isDoingSomething()==false) 
      throw new Exception ("Something went wrong"); 
    } 
} 

版本

春季啓動1.5.4.RELEASE,

的Java 1.8

+0

我對你遇到的問題有點困惑......問題只是你不希望Spring在測試過程中初始化'StartupConfiguration'? –

+0

我需要StartupConfiguration未加載測試,以便監聽程序根本不執行。 – Rittmann

+0

另一種方法是嘲笑應用程序監聽器返回true,但如果內部模擬服務在啓動時沒有初始化,我的猜測是嘲笑它也是不可能的。但如果可能的話,那也可以。 – Rittmann

回答

0

謝謝,araxn1d。你的回答給了我解決這個問題的線索。

我嘲笑在TestUnit.java的StartupConfiguration類:

@MockBean 
private StartupConfiguration startupConfiguration; 

儘管在這種情況下,我是幸運的:應用程序的用戶不知道回來的方法,所以他們並不需要在測試配置。如果我要求某個方法返回例如true或value,則此方法不適用。

但至少對於應用程序監聽者來說,這就夠了。

0

您可以創建同一類型的模擬豆與@Primary註釋標記它來代替真正的豆。您可以通過測試具有這樣的配置實現這一點:

@Configuration 
@Import(TestApplication.class) 
public class TestConfiguration { 
    @Bean 
    @Primary 
    public ConfigurationService configurationService() { 
     return Mockito.mock(ConfigurationService.class); 
    } 
} 

然後測試得到這個模擬:

... 
public class TestConfigurationService { 
    ... 
    @Autowired 
    ConfigurationService configurationService; 

    @Before 
    public void setUp() { 
     when(mockService.isDoingSomething()).thenReturn(true); 
    } 
} 
+0

這就是'@ MockBean'已經在做的事情。不要將它與Mockito的'@ Mock'混淆。 –

+0

@ M.Deinum,是的,我錯過了,現在我的答案毫無價值=( – rxn1d

相關問題