@RunWith(SpringRunner.class)与@RunWith(MockitoJUnitRunner.class)
我使用@RunWith(SpringRunner.class)与@RunWith(MockitoJUnitRunner.class),junit,mockito,spring-test,Junit,Mockito,Spring Test,我使用@RunWith(MockitoJUnitRunner.class)进行我的带有mockito的junit测试。但现在我正在使用SpringBoot应用程序,并尝试使用@RunWith(SpringRunner.class)。使用@RunWith(SpringRunner.class)是否比使用@RunWith(MockitoJUnitRunner.class)有任何优势?我是否仍然可以将@Injectmock、@Mock、@Spy等功能与@RunWith(SpringRunner.cla
@RunWith(MockitoJUnitRunner.class)
进行我的带有mockito的junit测试。但现在我正在使用SpringBoot应用程序,并尝试使用@RunWith(SpringRunner.class)
。使用@RunWith(SpringRunner.class)
是否比使用@RunWith(MockitoJUnitRunner.class)
有任何优势?我是否仍然可以将@Injectmock
、@Mock
、@Spy
等功能与@RunWith(SpringRunner.class)
一起使用SpringRunner.class
时,Spring提供了相应的注释:
@MockBean
@SpyBean
@Autowired
注释注入测试对象。若要启用此功能,必须使用注释对测试进行注释
@SpringBootTest
@TestExecutionListeners(MockitoTestExecutionListener.class)
更多详细信息和示例可在官方文档中找到:SpringRunner支持加载Spring
ApplicationContext
并将bean@Autowired
加载到测试实例中。它实际上做的远不止这些(在Spring参考手册中有介绍),但这是它的基本思想
然而,MockitoJUnitRunner
提供了对使用Mockito创建mock和间谍的支持
但是,对于JUnit4,一次只能使用一个运行程序
因此,如果您想同时使用Spring和Mockito的支持,您只能选择其中一个跑步者
但是你很幸运,因为Spring和Mockito都提供了跑步者之外的规则
例如,可以将Spring runner与Mockito规则一起使用,如下所示
@RunWith(SpringRunner.class)
@春靴测试
公共类MyTests{
@统治
public MockitoRule rule=MockitoJUnit.rule();
@嘲弄
我的服务我的服务;
// ...
}
但是,通常情况下,如果您使用Spring Boot并且需要从SpringApplicationContext
模拟bean,那么您将使用Spring Boot的@MockBean
支持,而不是按照JavaDoc使用简单的@mock
:
SpringRunner是SpringJUnit4ClassRunner
的别名。
要使用这个类,只需使用@RunWith(SpringRunner.class)
注释一个基于JUnit4的测试类。
如果您想将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清理它
但是,这已经是一个集成或组件测试。如果您的测试是纯单元测试,那么您不必加载DB,或者您只想验证是否调用了某个依赖项方法,MockitoJUnit4Runner
就足够了。您只需随意使用@Mock
和Mockito。验证(…)
,测试就会通过。而且要快得多
测试应该很快。尽可能快。因此,只要有可能,就使用MockitoJUnit4Runner
来加快速度 您完全可以使用SpringRunner进行单元测试和集成测试。
场景2019年11月:春季开机:2.1.1.0版本
- 您有一个SpringBootAPI rest
- 您需要测试一个名为MySuperSpringService
- 但是,在MySuperSpringService内部,还需要两条自动线。一个用于执行sql选择(MyJpaRepository),另一个用于调用外部api rest(MyExternalApiRest)
如何测试MySuperSpringService模拟数据库和外部api rest?
因此,为了测试这个需要另一个SpringBeans:MyJpaRepository和MyExternalApiRest的服务MySuperSpringService,您需要使用@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
}
}
mock不能与Autowired一起注入,您应该使用MockBeaninstead@voippmock可以使用Autowired注入到测试对象中,但MockBean用于定义要注入的mock如何替换@RunWith(SpringRunner.class)使用类似于您为MockitoJUnit所做的规则?使用SpringClassRule
和SpringMethodRule
:还有一个想法:)我可以将其与PowerMock规则结合使用还是与PowerMock同步运行:)?我不使用PowerMock,所以很遗憾我无法回答这个问题。例如,在测试Spring数据接口时,我使用@MockBean
,但在测试JPA查询实现类时,我使用@Mock
两个问题。。。是否需要@springbootest
,我们是否需要@MockBean
?这可以用@Mock
简单地完成吗?@SpringBootTest是测试的超级必备工具!!@Mock用于简单的java类。如果目标类是一个包含多个@autowireddentro的spring组件,@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
}
}