簡體   English   中英

如何在 Spring Boot 中用測試模擬替換 bean 以進行集成測試

[英]How to replace a bean with a testing mock in Spring Boot for integration testing

我有一個 spring 應用程序和此應用程序的集成測試。 我想用模擬 bean 替換 bean。

我真正的豆子是這樣的

@Service
public class MyService {

}

並且為了測試我希望它被替換

@Service
public class TestMyService {

}

我能想到的就是為不同的服務使用配置文件。 例如:

@Service
@Profile("!test")
public class MyService implements IMyService {

}

@Service
@Profile("test")
public class TestMyService implements IMyService {

}

然后我像這樣自動裝配bean

@Autowired
private IMyService myService;

有沒有更好的辦法?

我個人的喜好是避免加載競爭環境進行測試。 因此,我希望我的測試專注於豆子集。 這通常意味着我概述了在測試中使用的bean:

@RunWith(SpringRunner.class)
@SpringBootTest(
        classes = {TestMyService.class, OtherClassNeededForTesting.class}
)
public class DelaysProviderTest {

}

如果需要更多配置,我傾向於准備單獨的配置類以進行測試:

@RunWith(SpringRunner.class)
@SpringBootTest(
        classes = MyTest.Cfg.class
)
public class MyTest {

    @Import({
        // .. some classes to import including TestMyService.class
    })
    @Configuration
    public static class Cfg {

    }

}

當需要更多配置(或模擬)時,我使用測試配置來提供適當的模擬

@RunWith(SpringRunner.class)
@SpringBootTest(
        classes = MyTest.Cfg.class
)
public class MyTest {

    @Import({
        // .. some classes to import
    })
    @Configuration
    public static class Cfg {

        @Bean
        public IMyService service() {
            IMyService mock = Mockito.mock(IMyService.class);
            when(mock.someMethod()).thenReturn("some data");

            return mock;
        }

    }

}

您可以命名您的豆子,例如

@Service("testService")    
public class TestMyService implements IMyService {

}

在您的測試課程中,您可以使用@Qualifier明確要求測試服務,例如

@Qualifier("testService")
@Autowired
private IMyService myService;

Spring Boot正是為此目的提供了@MockBean@SpyBean批注:

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-mocking-beans

聲明很簡單:

@MockBean
private MyService myService;

Spring Boot將在此處注入Mockito模擬,而不是實際的bean。

對於 Spring 引導, @MockBean (和@SpyBean )可能是您在 Grzegorz Poznachowski 的回答中指出的最佳選擇。

對於非 Spring 引導應用程序,另一種方法是使用@Primary來注釋模擬/存根@Bean / @Service定義。 該注釋“表明當多個候選者有資格自動裝配單值依賴項時,應優先考慮 bean”。 因此,在連接其他 Bean/配置時,您的模擬將用於“真實”模擬。

@SpringJUnitWebConfig(MyAppConfig.class)
public class MyUintTest 
{
    @Autowired
    private ServiceInterface serviceMock;

    @Autowired
    private SomeClass someClassMock;

    @Test
    public void myTest() 
    {
        when(someClassMock.getProperty()).thenReturn(properties.get());
        // . . .
    }

    @Service
    @Primary
    static class TestService implements ServiceInterface 
    {
        // . . .
    }

    @Configuration
    static class Config 
    {
        @Bean
        @Primary
        public SomeClass someClassBean() 
        {
            return Mockito.mock(SomeClass.class);
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM