我使用@RunWith(MockitoJUnitRunner.class)
进行了与mockito的junit测试。但现在我正在使用spring boot app并尝试使用@RunWith(SpringRunner.class)
。使用@RunWith(SpringRunner.class)
比使用@RunWith(MockitoJUnitRunner.class)
有什么优势吗?我仍然可以使用@Injectmock
,@Mock
,@Spy
等@RunWith(SpringRunner.class)
答案 0 :(得分:14)
SpringRunner
支持将Spring ApplicationContext
和bean @Autowired
加载到测试实例中。 它确实比它更多(在Spring参考手册中有所介绍),但这是基本的想法。
然而,MockitoJUnitRunner
支持使用Mockito创建模拟和间谍。
但是,对于JUnit 4,您一次只能使用一个Runner
。
因此,如果你想同时使用Spring和Mockito的支持,你只能选择一个的那些跑步者。
但是你很幸运,因为除了 runners 之外,Spring和Mockito都提供规则。
例如,您可以使用带有Mockito规则的Spring runner,如下所示。
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTests {
@Rule
public MockitoRule rule = MockitoJUnit.rule();
@Mock
MyService myService;
// ...
}
但是,通常,如果您正在使用Spring Boot并且需要从Spring ApplicationContext
模拟 bean ,那么您将使用Spring Boot' s {{1支持而不仅仅是@MockBean
。
答案 1 :(得分:4)
当使用SpringRunner.class
时,Spring提供相应的注释:
@MockBean
@SpyBean
通过@Autowired
注释将模拟注入到测试对象中。要启用此功能,必须使用
@SpringBootTest
或
@TestExecutionListeners(MockitoTestExecutionListener.class)
更多详细信息和示例可在官方文档中找到:Mocking and Spying Beans
答案 2 :(得分:2)
根据JavaDoc:
SpringRunner是
SpringJUnit4ClassRunner
的别名。 要使用此类,只需用@RunWith(SpringRunner.class)
注释基于JUnit 4的测试类即可。 如果您想将SpringTestContext
框架与其他运行程序一起使用,请使用org.springframework.test.context.junit4.rules.SpringClassRule
和org.springframework.test.context.junit4.rules.SpringMethodRule
。
还有TestContext
的JavaDoc:
TestContext
封装了执行测试的上下文,而与使用的实际测试框架无关。
方法getApplicationContext()
的方法:
获取此测试上下文的应用程序上下文,可能已缓存。 如果尚未加载相应的上下文,则此方法的实现负责加载应用程序上下文,并可能还会缓存该上下文。
因此,SpringRunner确实加载了上下文并负责维护它。例如,如果要将数据持久存储到嵌入式数据库(例如H2内存数据库)中,则必须使用SpringRunner.class
;并且,要清理表以摆脱每次测试后插入的记录,请用@DirtiesContext
注释测试以告知Spring进行清理。
但是,这已经是集成或组件测试。如果您的测试是纯单元测试,则不必加载数据库,或者您只想验证某种依赖项方法(MockitoJUnit4Runner
就足够了)。您可以随意使用@Mock
和Mockito.verify(...)
,然后测试就会通过。而且速度更快。
测试应该很快。尽可能快地。因此,请尽可能使用MockitoJUnit4Runner
加快速度。
答案 3 :(得分:1)
@Service
public class MySuperSpringService {
@Autowired
private MyRepository innerComponent1;
@Autowired
private MyExternalApiRest innerComponent2;
public SomeResponse doSomething(){}
}
因此,为了测试该服务 MySuperSpringService ,该服务需要另一个spring bean:MyJpaRepository和MyExternalApiRest,您需要使用 @MockBean 对其进行模拟并在您创建结果时需要。
import static org.mockito.Mockito.when;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import junit.framework.TestCase;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = your.package.Application.class)
public class MySuperSpringServiceTest extends TestCase {
@Autowired
private MySuperSpringService serviceToTest;
@MockBean
private MyRepository myRepository;
@MockBean
private MyExternalApiRest myExternalApiRest;
@Before
public void setUp() {
Object myRepositoryResult = new Object();
//populate myRepositoryResult as you need
when(myRepository.findByClientId("test.apps.googleusercontent.com"))
.thenReturn(myRepositoryResult);
Object myExternalApiRestResult = new Object();
//populate myExternalApiRestResult as you need
when(myExternalApiRest.listUserRoles("john@doe.com")).thenReturn(myExternalApiRestResult);
}
@Test
public void testGenerateTokenByGrantTypeNoDatabaseNoGoogleNoSecurityV1(){
SomeResponse response = serviceToTest.doSomething();
//put your asserts here
}
}
答案 4 :(得分:0)
您绝对可以将SpringRunner用于单元测试和集成测试。 SpringRunner Tutorial