单元测试(UnitTesting),又称模块测试,是对程序模块(软件设计的最小单元)正确性的测试。程序单元是应用程序的最小可测试组件。简单的说就是测试数据的稳定性是否达到程序的预期。说到测试,我们为什么要测试程序?测试给程序带来什么好处?单元测试的重要性我们在日常开发中可能会不经意地写出错误。如果我们等到最后阶段检查项目结果时发现错误,我们将很难找到错误的来源。我们都知道,有可能犯一个错误并导致一步错误。在我们上面的声明中,测试尤为重要。当我们完成项目的一个小模块时,我们首先测试这个小模块是否正确或者是否符合预期。如有错误或不符合预期,需反复修改,直至正确或不正确。达到预期,即使用单元测试。单元测试的编码规范一般涉及以下内容:类名:定义测试类,类名由被测类名Test组成。例如:计算器测试;包名:定义的测试类需要放在xxx.xxx.xxx.test包中。例如:包com.autodrive.test;方法名:定义测试方法的方法名有两种方式:测试方法和测试方法。例如:testCheck和检查;返回值:因为我们的方法只是在类中测试,可以独立运行,不需要处理任何返回值,所以这里使用void。例如:publicvoidcheck();parameterlist:因为我们的方法是用来测试的,所以不需要传入parameterlist。我们在测试的时候可以传入测试需要的参数。所以这里的参数列表是空的。例如:例如:publicvoidcheck();@Test注解:测试需要运行才能完成。如果我们只有一个主要方法,显然在结构上我们仍然需要注释掉被测试的方法。为了解决这个问题,我们需要在测试方法上方添加@Test注解来完成测试。只要是有这个注解的方法,就可以单独运行这个方法来完成测试。IDEA快速导入Junit4、5:使用IDEA的朋友们,你们的福音来了。我们可以先创建测试类和方法,然后在测试方法上面加上@Test注解。此时IDEA显示的@Test注解是红色的。这时候我们使用Alt+Enter组合键打开导入Junit单元测试列表,然后选择Junit4或者Junit5进行确认。在SpringBoot中,经常有单元测试使用下面的注解和写法:@RunWith(SpringRunner.class)@SpringBootTest(classes=Application.class)@Transactional@Rollback(true)//事务自动回滚,并且默认为真。没有必要写publicclassNoticeServiceTest{@AutowiredprivateNoticeServicenoticeService;@TestpublicvoidsayHello(){helloService.sayHello("zhangsan");}}上面的例子中,@SpringBootTest启动SpringBoot环境,扫描应用的springConfigure,构建一个完整的SpringContext,其classes=Application.class启动整个项目。通过@SpringBootTest我们可以指定启动类,或者将@SpringBootTest的参数webEnvironment赋值给SpringBootTest.WebEnvironment.RANDOM_PORT,它会启动web容器并监听一个随机端口。同时会自动为我们组装一个TestRestTemplate类型的bean。帮助我们发送测试请求。@Transactional表示调用数据库,做事务处理;@RunWith(SpringRunner.class)在Spring环境中声明单元测试,这样Spring的相关注解就会被识别并生效,@Autowired启动Spring。当项目使用@Component注解时,会在SpringBoot项目启动时实例化/启动。这个@Component注释类具有多线程方法。它以启动类中定义的ApplicationStartup类开始。那么你在执行单元测试时,由于多线程任务的影响,你的数据库可能会发生数据修改,即使你使用了事务回滚注解。优化高效的单元测试应该与数据库分离,以满足快速启动和完成测试以及支持服务间调用的需求。上面的例子可以通过以下几点进行优化:(1)running->JunitTest时启动Spring会导致程序变慢,这也是每次运行单元测试都慢的原因之一。然后单元测试只针对某个类的方法进行测试。启动Spring往往是多余的,所以我们只需要相应的实体类实例即可。当我们需要注入bean的时候,我们直接new。privateNoticeServicenoticeService=newNoticeService();(2)SpringBoot项目上使用了@SpringBootTest。基于@SpringBootContextLoader,读取并解析一些项目配置文件,并连接到配置文件Database的属性,然后如果启动类有其他启动类,@Component,多线程等,单元测试往往可以避免启动SpringBoot,减少大量的启动时间,即不使用@SpringBootTest注解。(3)应使用断言来判断单元测试结果是否符合预期。(4)@RunWithJUnit中有很多Runner。他们负责调用特定的测试代码。每个Runner都有自己的特殊功能。你需要根据自己的需要选择不同的Runner来运行你的测试代码,一般使用SpringRunner.class。如果我们只是做普通的Java测试,不涉及SpringWeb项目,可以省略@RunWith注解,这样系统会自动使用默认的Runner来运行你的代码。(5)单元测试可以避免通过Mock数据的方式调用数据库,减少大量的数据库连接时间。Mock是在不执行任何SQL的情况下模拟操作数据库的所有步骤。如果我们直接模拟执行这段代码来操作数据库,就可以成功,可以模拟任何返回值。有两个主要注释。只要是本地的,你自己写的任何bean都可以使用@MockBean,它会模拟操作数据库的所有方法。如果是没有返回值的方法,我们可以忽略。如果是有返回值的方法,我们可以返回我们需要模拟的值。如果是我们本地,调用其他公司,其他地方给我们写接口,而不是操作我们自己的数据库,我们写入参,其他返回值给我们,我们用@SpyBean。Mock需要以下依赖:
