Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
@RunWith(SpringRunner.class)与@RunWith(MockitoJUnitRunner.class)_Junit_Mockito_Spring Test - Fatal编程技术网

@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并且需要从Spring
ApplicationContext
模拟bean,那么您将使用Spring Boot的
@MockBean
支持,而不是按照JavaDoc使用简单的
@mock

SpringRunner是
SpringJUnit4ClassRunner
的别名。 要使用这个类,只需使用
@RunWith(SpringRunner.class)
注释一个基于JUnit4的测试类。 如果您想将Spring
TestContext
框架与此框架以外的运行程序一起使用,请使用
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
  }

}