SpringBoot test

SpringBoot test原文地址:https://www.jianshu.com/p/72b19e24a602前言mac上idea快捷键,command+shift+T根据类生成快捷键。对spring容器中的类做单元测试在src/main下建立UserService类,对其进行单于测试,生产其单元测试类(使用command+shift+T快捷键),生成的test类在src/test下@Servi…

大家好,又见面了,我是你们的朋友全栈君。

原文地址:https://www.jianshu.com/p/72b19e24a602

前言

mac上idea快捷键,command+shift+T根据类生成快捷键。

对spring容器中的类做单元测试

在src/main下建立UserService类,对其进行单于测试,生产其单元测试类(使用command+shift+T快捷键),生成的test类在src/test下

@Service
public class UserService {

    public Integer addUser(String username){
        System.out.println("user dao adduser [username="+username+"]");
        if(username == null){
            return 0;
        }
        return 1;
    }
}

springboot启动类:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

测试类:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void addUser() throws Exception {
        Assert.assertEquals(Integer.valueOf(1),userService.addUser("zhihao.miao"));
        Assert.assertEquals(Integer.valueOf(0),userService.addUser(null));
    }

}

盲点扫描

RunWith注解,SpringRunner类,SpringJUnit4ClassRunner类,SpringBootTest注解的解释。

SpringBoot test

RunWith注解

When a class is annotated with @RunWith or extends a class annotated with @RunWith, JUnit will invoke the class it references to run the tests in that class instead of the runner built into JUnit. We added this feature late in development. While it seems powerful we expect the runner API to change as we learn how people really use it. Some of the classes that are currently internal will likely be refined and become public.
当一个类用@RunWith注释或继承一个用@RunWith注释的类时,JUnit将调用它所引用的类来运行该类中的测试而不是开发者去在junit内部去构建它。我们在开发过程中使用这个特性。

For example, suites in JUnit 4 are built using RunWith, and a custom runner named Suite:
比如说,suites使用RunWith注解构建,

@RunWith(Suite.class)
@SuiteClasses({ATest.class, BTest.class, CTest.class})
public class ABCSuite {
}

SpringBoot test

SpringRunner注解

SpringRunner is an alias for the SpringJUnit4ClassRunner.
SpringRunnerSpringJUnit4ClassRunner的一个别名。

To use this class, simply annotate a JUnit 4 based test class with @RunWith(SpringRunner.class).
使用这个类,简单注解一个JUnit 4 依赖的测试@RunWith(SpringRunner.class).

If you would like to use the Spring TestContext Framework with a runner other than
this one, use org.springframework.test.context.junit4.rules.SpringClassRule
and org.springframework.test.context.junit4.rules.SpringMethodRule.
如果你想使用Spring测试上下文而不是使用这个,你可以使用org.springframework.test.context.junit4.rules.SpringClassRuleorg.springframework.test.context.junit4.rules.SpringMethodRule.

SpringBoot test

SpringJUnit4ClassRunner

SpringJUnit4ClassRunner is a custom extension of JUnit’s
BlockJUnit4ClassRunner which provides functionality of the
Spring TestContext Framework to standard JUnit tests by means of the
TestContextManager and associated support classes and annotations.
SpringJUnit4ClassRunner是JUnit’s的BlockJUnit4ClassRunner类的一个常规扩展,提供了一些spring测试环境上下文去规范JUnit测试,意味着TestContextManager和支持相关的类和注解。

SpringBoot test

SpringBootTest注解

Annotation that can be specified on a test class that runs Spring Boot based tests.
Provides the following features over and above the regular Spring TestContext
Framework:
注解制定了一个测试类运行了Spring Boot环境。提供了以下一些特性:

Uses SpringBootContextLoader as the default ContextLoader when no specific ContextConfiguration#loader() @ContextConfiguration(loader=…) is defined.
当没有特定的ContextConfiguration#loader()(@ContextConfiguration(loader=…))被定义那么就是SpringBootContextLoader作为默认的ContextLoader。

Automatically searches for a SpringBootConfiguration @SpringBootConfiguration when nested @Configuration is not used, and no explicit #classes() classes are
specified.
自动搜索到SpringBootConfiguration注解的文件。

Allows custom Environment properties to be defined using the properties() properties attribute}.
允许自动注入Environment类读取配置文件。

Provides support for different #webEnvironment() webEnvironment modes,
including the ability to start a fully running container listening on a
WebEnvironment#DEFINED_PORT defined or WebEnvironment#RANDOM_PORT
random port.
提供一个webEnvironment环境,可以完整的允许一个web环境使用随机的端口或者自定义的端口。

Registers a org.springframework.boot.test.web.client.TestRestTemplate
TestRestTemplate bean for use in web tests that are using a fully running container.
注册了TestRestTemplate类可以去做接口调用。

springboot测试步骤

  • 直接在测试类上面加上如下2个注解
    @RunWith(SpringRunner.class)
    @SpringBootTest
    就能取到spring中的容器的实例,如果配置了@Autowired那么就自动将对象注入。

在测试环境中获取一个bean,在项目中新建User类,然后在测试模块进行测试

在src/main下新建一个实例User

@Component
public class User {
}

src/test下创建测试类测试:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserTest {


    @Autowired
    public ApplicationContext context;

    @Test
    public void testNotNull(){
        Assert.assertNotNull(context.getBean(User.class));
    }
}

只在测试环境有效的bean

在src/test下新建二个类,我们发现分别使用@TestComponent和@TestConfiguration二个注解修饰,这些类只在测试环境生效

@TestComponent
public class Cat {

    public void index(){
        System.out.println("cat index");
    }
}
@TestConfiguration
public class TestBeanConfiguration {

    @Bean
    public Runnable createRunnable(){
        return () -> System.out.println("=====createRunnable=======");
    }
}

测试类:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {TestBeanConfiguration.class,Cat.class})
public class TestApplication {

    @Autowired
    public ApplicationContext context;

    @Test
    public void testNotNull(){
        Runnable runnable = context.getBean(Runnable.class);
        runnable.run();
        System.out.println("--------");

        Cat cat = context.getBean(Cat.class);
        cat.index();
    }
}

需要在@SpringBootTest注解的参数classes中加入参数,表示将某些类纳入测试环境的容器中。

SpringBoot test

TestComponent注解

SpringBoot test

TestConfiguration注解

配置文件属性的读取

springboot会只会读取到src/test/resources下的配置,不会读到正式环境下的配置文件(跟以前1.4.*版本的不一样,以前是优先读取测试环境配置文件,然后读取正式环境的配置)

@RunWith(SpringRunner.class)
@SpringBootTest
public class EnvTest {

    @Autowired
    public Environment environment;

    @Test
    public void testValue(){
        Assert.assertEquals("zhihao.miao",environment.getProperty("developer.name"));

    }
}

除了在配置文件中设置属性,测试环境加载一些配置信息的二种方式:
第一种是使用@SpringBootTest注解,注解参数properties指定其value值,第二种使用EnvironmentTestUtils.addEnvironment方法进行设置。
测试:

@RunWith(SpringRunner.class)
@SpringBootTest(properties = {"app.version=1.0"})
public class EnvTest2 {

    @Autowired
    private ConfigurableEnvironment environment;

    @Before
    public void init(){
        EnvironmentTestUtils.addEnvironment(environment,"app.admin.user=zhangsan");
    }

    @Test
    public void testApplication(){
        Assert.assertEquals("1.0",environment.getProperty("app.version"));
        Assert.assertEquals("zhangsan",environment.getProperty("app.admin.user"));
    }
}

Mock方式的测试

正式环境只是一个接口,并没有实现,也并没有纳入spring容器进行管理。

public interface UserDao {
    Integer createUser(String userName);
}

测试

@RunWith(SpringRunner.class)
public class UserDaoTest {

    //使用MockBean是因为此时容器中没有UserMapper这个对象
    @MockBean
    public UserDao userDao;

    //使用BDDMockito对行为进行预测,
    @Before
    public void init(){
        BDDMockito.given(userDao.createUser("admin")).willReturn(1);
        BDDMockito.given(userDao.createUser("")).willReturn(0);
        BDDMockito.given(userDao.createUser(null)).willThrow(NullPointerException.class);
    }

    @Test(expected=NullPointerException.class)
    public void testCreateUser() {
        Assert.assertEquals(Integer.valueOf(1),userDao.createUser("admin")) ;
        Assert.assertEquals(Integer.valueOf(0),userDao.createUser("")) ;
        Assert.assertEquals(Integer.valueOf(1),userDao.createUser(null)) ;
    }
}

对controller进行测试

第一种方式:
定义一个Controller,用作测试:

@RestController
public class UserController {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @GetMapping("/user/home")
    public String home(){
        logger.info("user home");
        return "user home";
    }

    @GetMapping("/user/show")
    public String show(@RequestParam("id") String id){
        logger.info("book show");
        return "show"+id;
    }
}

使用浏览器访问

http://localhost:8080/user/home
http://localhost:8080/user/show?id=100

使用测试类测试

@RunWith(SpringRunner.class)
//指定web环境,随机端口
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserControllerTest {

    //这个对象是运行在web环境的时候加载到spring容器中
    @Autowired
    private TestRestTemplate testRestTemplate;

    @Test
    public void testHome(){
        String context = testRestTemplate.getForObject("/user/home",String.class);
        Assert.assertEquals("user home",context);
    }

    @Test
    public void testShow(){
        String context = testRestTemplate.getForObject("/user/show?id=100",String.class);
        Assert.assertEquals("show10",context);
    }
}

第二种方式,使用@WebMvcTest注解

@RunWith(SpringRunner.class)
@WebMvcTest(controllers = UserController.class)
public class UserControllerTest2 {

    @Autowired
    public MockMvc mockMvc;

    @Test
    public void testHome() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/user/home")).andExpect(MockMvcResultMatchers.status().isOk());
        mockMvc.perform(MockMvcRequestBuilders.get("/user/home")).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().string("user home"));
    }

    @Test
    public void testShow() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/user/show").param("id", "400")).andExpect(MockMvcResultMatchers.status().isOk());
        mockMvc.perform(MockMvcRequestBuilders.get("/user/show").param("id", "400")).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().string("show400"));
    }
}

SpringBoot test

WebMvcTest

@WebMvcTest 不需要运行在web环境下,但是,需要指定controllers,表示需要测试哪些controllers。
这种方式只测试controller,controller里面的一些依赖,需要你自己去mock
@WebMvcTest 不会加载整个spring容器。

第三种方式
使用@SpringBootTest()与@AutoConfigureMockMvc结合,@SpringBootTest使用@SpringBootTest加载测试的spring上下文环境,@AutoConfigureMockMvc自动配置MockMvc这个类,

/**
 * @SpringBootTest 不能和  @WebMvcTest 同时使用
 * 如果使用MockMvc对象的话,需要另外加上@AutoConfigureMockMvc注解
 */
@RunWith(SpringRunner.class)
@SpringBootTest()
@AutoConfigureMockMvc
public class UserControllerTest3 {

    @Autowired
    private MockMvc mvc;

    @Test
    public void testHome() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/user/home")).andExpect(MockMvcResultMatchers.status().isOk());
        mvc.perform(MockMvcRequestBuilders.get("/user/home")).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().string("user home"));
    }

    @Test
    public void testShow() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/user/show").param("id", "400")).andExpect(MockMvcResultMatchers.status().isOk());
        mvc.perform(MockMvcRequestBuilders.get("/user/show").param("id", "400")).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().string("show400"));
    }
}

一个注解可以使测试类可以自动配置MockMvc这个类。

 

SpringBoot test

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/130395.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • APK签名流程详解

    APK签名流程详解本文最好对照我的APK签名解析示例进行阅读.示例中的关键文件说明:keys-存放签名公私钥的目录signed_logcat.apk-已经使用keys目录中的密钥签名后的apksigned_logcat-signed_logcat.apk解压出来的内容sign.cmd-对apk签名的批处理命令signapk.jar-java版本的apk签名工具

    2022年5月11日
    34
  • java软件工程师前景_培养java工程师

    java软件工程师前景_培养java工程师从各大招聘网上我们就能看出,同等软件工程师的就业前景是远比网络工程师就业前景要好很多,年薪在10万以上的软件工程师还只是一个起点,随着经验的增加,年薪超20万的也是很常见的,而其它专业的发展前景是远比不上Java软件工程师的就业前景的。Java软件工程师就业前景为什么这么好呢?原因之一:软件工程师可谓是软件项目开发的掌舵者,一名优秀的软件工程师应当具有较强的逻辑思维能力,对于技术的发展有敏锐的嗅觉…

    2022年9月23日
    3
  • random.nextInt()的用法

    random.nextInt()的用法1、不带参数的nextInt()会生成所有有效的整数(包含正数,负数,0)2、带参的nextInt(intx)则会生成一个范围在0~x(不包含X)内的任意正整数例如:intx=newRandom.nextInt(100);则x为一个0~99的任意整数3、生成一个指定范围内的整数/**生成[min,max]之间的随机整数*@parammin最小整数…

    2022年7月22日
    13
  • directshow是什么_showpoint

    directshow是什么_showpoint1.DirectShow介绍DirectShow是一个windows平台上的流媒体框架,提供了高质量的多媒体流采集和回放功能。它支持多种多样的媒体文件格式,包括ASF、MPEG、AVI、MP3和WAV文件,同时支持使用WDM驱动或早期的VFW驱动来进行多媒体流的采集。DirectShow整合了其它的DirectX技术,能自动地侦测并使用可利用的音视频硬件加速,也能支持没有硬件加速的系统。DirectShow大大简化了媒体回放、格式转换和采集工作。但与此同时,它也为用户自定义的解决方…

    2022年10月12日
    2
  • 物理讨论题复习

    物理讨论题复习请简要回答避雷针的工作原理?避雷针由于曲率半径小,电荷面密度大,从而产生尖端放电现象,导致自身与带电云层形成回路。导致自身电荷放出从而不会被雷击中,当带电云层密度过大,避雷针通过接地把电引下大地“分子电流假说“是谁提出的?请解释“分子电流”。安培。在原子、分子等物质微粒内部,存在着一种环形电流—-分子电流。分子电流使每个物质都成为微小的磁体,他的两侧相当于两个磁极请解释”磁偶极子“。磁偶极子是类比电偶极子而建立的物理模型。具有等值异号的两个点磁荷构成的系统称为磁偶极子。磁偶极子的物理

    2025年6月29日
    3
  • getParameterValues使用

    getParameterValues使用request.getParameterValues:接收名字相同,值有多个的变量,返回一个数据。如: String[]courseNumbers=request.getParameterValues(“courseNumberForCourse”);request.getParameter:接收单一值变量。如:stringtype=request.getPara

    2022年7月22日
    18

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号