2026年Java后端开发单元测试专项训练试卷_第1页
2026年Java后端开发单元测试专项训练试卷_第2页
2026年Java后端开发单元测试专项训练试卷_第3页
2026年Java后端开发单元测试专项训练试卷_第4页
2026年Java后端开发单元测试专项训练试卷_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2026年Java后端开发单元测试专项训练试卷考试时间:______分钟总分:______分姓名:______一、选择题(每题2分,共20分)1.下列关于单元测试的说法中,错误的是?A.单元测试针对的是代码中最小的可测试单元,通常是方法或函数。B.单元测试的目的是验证代码单元是否按预期工作。C.单元测试需要模拟(Mock)所有外部依赖,以实现隔离性。D.单元测试应由开发人员编写,是软件开发过程的一部分。2.在JUnit5中,用于标记一个方法作为测试方法的注解是?A.`@BeforeAll`B.`@AfterEach`C.`@Test`D.`@ParameterizedTest`3.以下哪个断言用于检查一个对象是否为`null`?A.`assertEquals`B.`assertTrue`C.`assertNotNull`D.`assertThrows`4.在使用Mockito框架时,`mock(MyClass.class)`与`mock(newMyClass())`的主要区别在于?A.前者创建的Mock对象可以被Mockito跟踪所有方法调用,后者不能。B.前者性能更高,后者性能更低。C.两者没有区别,都创建一个不可变的Mock对象。D.前者需要指定类类型,后者需要实例化对象。5.`@BeforeEach`注解标记的方法,在每个测试方法执行之前,会只执行一次?A.正确B.错误6.如果你想编写一个测试用例,用不同的数据集(如用户ID1,2,3)来调用同一个测试方法,应该使用哪个注解?A.`@RepeatedTest`B.`@Test`C.`@ParameterizedTest`D.`@BeforeAll`7.在SpringBoot测试中,如果你只想加载特定的组件(如某个Service)进行测试,而不加载完整的Spring应用上下文,可以使用哪个注解?A.`@SpringBootTest`B.`@DataJpaTest`C.`@WebMvcTest`D.`@ComponentTest`(假设此注解存在,实际常用为B或C,此处按题意选择一个假设选项)8.当使用`Mockito`模拟一个依赖对象时,如果希望模拟对象在调用某个方法时不执行该方法本身,而是返回一个预设的值,应该使用`when(...).thenReturn(...)`结构。这种做法称为?A.模拟(Mocking)B.存根(Stubbing)C.打桩(Stubbing)D.探针(Spying)9.以下哪个原则对于编写可维护和可重用的单元测试至关重要?A.封装性B.单一职责原则C.开放/封闭原则D.接口隔离原则10.在进行单元测试时,验证一个服务层方法在调用其依赖的DAO层方法后,是否确实调用了该DAO方法,应该使用`Mockito`的哪个方法?A.`thenReturn()`B.`verify()`C.`doReturn().when()`D.`mock()`二、填空题(每空2分,共20分)1.单元测试的核心目标是验证代码单元的___是否正确,确保其行为符合预期。2.JUnit5中,用于在所有测试方法执行之前只运行一次设置代码的注解是___。3.当测试一个方法会抛出特定异常时,JUnit5提供的断言方法是___。4.在Mockito中,如果想要验证某个模拟对象的方法是否至少被调用了一次,可以使用`verify(mockObject).methodCall()`配合___方法。5.`@SpringBootTest`注解默认情况下会对数据库事务进行___,意味着测试方法执行后,对数据库的更改通常会被回滚。6.使用`MockMvc`可以进行对SpringMVC___层的测试,模拟HTTP请求并验证响应。7.编写单元测试时,遵循___原则,即测试应该独立于其他测试,不依赖于外部状态或服务。8.`Mockito`的`spy()`方法与`mock()`方法的主要区别在于,它会创建一个“监视器”,对于没有被Mock的方法调用,会执行实际对象的逻辑。9.衡量单元测试代码质量的一个常用指标是___,它表示测试用例覆盖了代码的百分比。10.在测试代码中,使用诸如`@DataJpaTest`、`@WebMvcTest`等轻量级配置时,通常会与`@AutoConfigureTestDatabase`结合使用,以提供一个___的数据库环境,方便测试。三、简答题(每题5分,共15分)1.简述使用Mockito进行单元测试时,“隔离依赖”的重要性体现在哪些方面?2.比较JUnit4和JUnit5在注解和断言方面的一个主要区别。3.当在SpringBoot应用中进行单元测试时,使用`@SpringBootTest`与不使用(例如仅使用`@DataJpaTest`)进行测试,在测试范围、应用上下文加载和事务管理等方面有什么主要不同?四、代码编写题(共45分)1.(15分)假设有以下一个简单的Java类和方法,该方法需要调用`databaseService`的`findRecordById`方法来获取数据,然后基于数据执行一些计算,最终返回一个结果字符串。```javaimportjava.util.Map;publicclassCalculatorService{privateDatabaseServicedatabaseService;//假设这是一个真实的数据库服务接口publicCalculatorService(DatabaseServicedbService){this.databaseService=dbService;}publicStringcalculateResult(intid){Map<String,Object>record=databaseService.findRecordById(id);if(record==null){return"RecordNotFound";}intvalue1=(Integer)record.get("value1");intvalue2=(Integer)record.get("value2");intsum=value1+value2;return"Sum:"+sum;}}//假设的数据库服务接口interfaceDatabaseService{Map<String,Object>findRecordById(intid);}```请编写JUnit5测试用例类`CalculatorServiceTest`,使用Mockito来模拟`DatabaseService`。编写至少两个测试方法:*`testCalculateResultFound`:测试当`findRecordById`返回包含`value1=10`和`value2=20`的记录时,`calculateResult`方法返回正确的字符串“Sum:30”。*`testCalculateResultNotFound`:测试当`findRecordById`返回`null`时,`calculateResult`方法返回字符串“RecordNotFound”。请在测试类中包含必要的导入语句,并确保使用了`@Test`注解和`@Mock`注解来创建模拟对象。2.(30分)假设你正在使用SpringBoot进行开发,有一个简单的REST控制器用于处理用户信息的获取请求。```javaimportorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.PathVariable;importorg.springframework.web.bind.annotation.RestController;importjava.util.HashMap;importjava.util.Map;@RestControllerpublicclassUserController{privateMap<String,String>userDatabase=newHashMap<>();publicUserController(){userDatabase.put("user1","Alice");userDatabase.put("user2","Bob");}@GetMapping("/users/{userId}")publicStringgetUserById(@PathVariableStringuserId){Stringname=userDatabase.get(userId);if(name==null){return"Usernotfound";}return"User"+userId+":"+name;}}```请编写一个JUnit5测试用例类`UserControllerTest`,使用`MockMvc`来测试`UserController`。编写至少两个测试方法:*`testGetUserFound`:测试当访问`/users/user1`时,期望返回`Useruser1:Alice`。*`testGetUserNotFound`:测试当访问`/users/user3`时,期望返回`Usernotfound`。请确保在测试类中:*使用`@SpringBootTest`注解加载SpringBoot应用上下文。*使用`@Autowired`注解注入`MockMvc`实例。*配置`MockMvc`以加载`UserController`的bean。*使用`MockMvc`的`perform`方法发送GET请求,并使用`andExpect`方法验证响应内容。试卷答案一、选择题1.C解析:单元测试需要模拟外部依赖以实现隔离,但并非所有外部依赖都必须模拟,例如某些不可控的外部服务或基础设施。2.C解析:`@Test`是JUnit5中用于标记测试方法的standard注解。3.C解析:`assertNotNull(Objectobject)`用于检查传入的对象是否不为`null`。4.A解析:`mock(MyClass.class)`创建一个Mockito会跟踪其所有方法调用的Mock对象,而`mock(newMyClass())`创建的是一个“哑”(Dummy)对象,不会跟踪方法调用。5.B解析:`@BeforeEach`注解标记的方法在每个测试方法执行之前,会对每个测试方法都执行一次。6.C解析:`@ParameterizedTest`允许开发者编写一个测试方法,该方法可以从外部数据源(如数组、列表、CSV文件等)获取多个参数,对每个参数组合执行相同的测试逻辑。7.C解析:`@WebMvcTest`用于加载SpringMVC相关的bean(如Controller、ControllerAdvice等),但不加载完整的应用上下文,适合测试单个控制器层。8.B解析:在Mockito中,设置模拟对象在调用时返回预设值的行为称为存根(Stubbing)。9.B解析:单一职责原则(SingleResponsibilityPrinciple)表明一个类应该只有一个引起它变化的原因。在单元测试中应用此原则,意味着一个测试类或测试方法应该只关注验证一个特定的功能或逻辑,使其更易于理解和维护。10.B解析:`verify()`是Mockito用于验证模拟对象的行为,即是否被调用、调用次数、调用参数等。二、填空题1.行为解析:单元测试的核心是验证代码单元(如方法)的实际行为是否符合预期。2.`@BeforeAll`解析:`@BeforeAll`注解标记的方法包含初始化代码,这些代码在所有测试方法执行之前,只执行一次。3.`assertThrows(Class<?extendsThrowable>expectedExceptionClass)`解析:这是JUnit5中用于验证期望抛出特定异常的断言方法。4.`atLeastOnce`解析:与`verify()`方法一起使用,表示验证某个模拟对象的方法调用至少被调用了一次。5.回滚解析:`@SpringBootTest`注解默认配置(通过`@Transactional`)会对测试方法执行后的数据库事务进行回滚,保持数据库的清洁状态。6.控制器解析:`MockMvc`主要用于测试SpringMVC的控制器层,能够模拟HTTP请求并验证控制器层的响应。7.独立性解析:测试独立性是单元测试的重要原则,要求一个测试用例不应该依赖于其他测试用例的执行结果,也不应该依赖外部环境或状态。8.监视器解析:`spy()`方法创建的是一个“监视器”,对于没有被Mock的方法调用,会执行实际对象的逻辑。9.覆盖率解析:代码覆盖率是衡量测试用例对代码逻辑覆盖程度的指标,常用百分比表示。10.内存解析:在SpringBoot测试中使用轻量级配置(如`@DataJpaTest`)时,通常与`@AutoConfigureTestDatabase`(如`autoConfigureTestDatabase=AutoConfigureTestDatabase.InMemory`)结合,提供一个内存数据库环境,方便快速测试,且无需配置真实的数据库。三、简答题1.简述使用Mockito进行单元测试时,“隔离依赖”的重要性体现在哪些方面?解析:隔离依赖是指在进行单元测试时,将被测试的代码单元(如一个方法)与其所需的外部依赖(如其他类、数据库、网络服务、文件系统等)隔离开来。其重要性体现在:*确保测试的独立性:每个测试用例应该独立运行,不依赖于其他测试或外部环境的状态。隔离依赖使得测试不受外部因素干扰,结果稳定可靠。*提高测试的速度和稳定性:模拟外部依赖(如数据库查询、网络请求)通常比实际调用要快得多,并且不受网络延迟、数据库状态变化等不稳定因素的影响,从而大大提高测试执行速度和成功率。*聚焦于单一功能点:通过模拟依赖,测试可以更专注于验证被测试单元本身的逻辑正确性,而不需要处理复杂的依赖交互或外部环境问题。*便于重构和开发:当依赖的外部服务发生变化时(例如更换数据库实现、修改第三方API),由于依赖被隔离和模拟,只需要更新模拟的行为,而无需修改测试用例本身,使得代码重构和开发更加安全。2.比较JUnit4和JUnit5在注解和断言方面的一个主要区别。解析:JUnit4和JUnit5在注解和断言方面存在显著变化,其中一个主要区别是断言的风格和结构:*JUnit4:主要使用基于JUnit3`assert`方法的断言风格。例如,使用`assertEquals(expected,actual)`、`assertTrue(condition)`、`assertNotNull(object)`等。这些断言方法直接作为静态方法调用,有时会感觉不够“声明式”。*JUnit5:引入了基于Java语言的`assert`语句的断言风格,使得断言更像是一种声明,代码更简洁、更具可读性。例如,使用`assertThat(actual).isEqualTo(expected)`、`assertTrue(condition)`、`assertNotNull(object)`等。`assertThat`形成一个表达式链,可以链式调用多个断言检查,使得错误信息更丰富,更容易表达复杂的断言逻辑。此外,JUnit5还引入了`assertThrows`等更完善的异常处理断言方法。3.当在SpringBoot应用中进行单元测试时,使用`@SpringBootTest`与不使用(例如仅使用`@DataJpaTest`)进行测试,在测试范围、应用上下文加载和事务管理等方面有什么主要不同?解析:`@SpringBootTest`和`@DataJpaTest`是SpringBootTest中用于配置测试环境的不同注解,它们在测试范围、加载的应用上下文和事务管理上存在主要区别:*测试范围:*`@SpringBootTest`:加载完整的Spring应用上下文,包括所有的beans(如Service、Repository、Controller、配置类等),应用上下文的加载方式与开发运行时类似。*`@DataJpaTest`:加载仅限于JPA相关的组件的Spring应用上下文,主要是SpringDataJPA的相关beans(如`EntityManagerFactory`,`TransactionManager`,Repository接口及其实现等)。它通常会默认配置一个内存数据库(如H2),并且不加载SpringMVC或其他非JPA相关的组件。*应用上下文加载:*`@SpringBootTest`:加载更全面的类路径扫描(默认扫描`package`下所有类),加载所有通过`@Component`,`@Service`,`@Repository`,`@Controller`等注解定义的beans。*`@DataJpaTest`:只扫描与JPA相关的包(默认是`package`下),只加载必要的beans来支持数据库操作。*事务管理:*`@SpringBootTest`:默认情况下,测试方法内的数据库事务在测试方法执行后回滚(除非显式禁用或配置为不回滚),以保持数据库的清洁状态。因为它加载了完整的应用上下文,所以事务管理可能与开发时的行为更一致。*`@DataJpaTest`:默认情况下,同样会管理事务,通常也是在测试方法执行后回滚。但由于它只加载了JPA相关的beans和一个内存数据库,其事务管理的配置可能更简单,且数据库状态需要开发者自己清理(例如通过`@DirtiesContext`或手动清理)。*总结:`@SpringBootTest`适用于需要测试整个Spring应用流程(如Service层与Controller层的交互、AOP切面等)的场景,但测试相对较慢,环境较重。`@DataJpaTest`适用于专注于测试数据访问层(Repository)逻辑的场景,速度更快,环境更轻量。四、代码编写题1.(15分)```javaimportorg.junit.jupiter.api.BeforeEach;importorg.junit.jupiter.api.Test;importorg.mockito.Mock;importorg.mockito.MockitoAnnotations;importstaticorg.mockito.Mockito.*;importstaticorg.junit.jupiter.api.Assertions.assertEquals;publicclassCalculatorServiceTest{@MockprivateDatabaseServicemockDatabaseService;//创建模拟对象privateCalculatorServicecalculatorService;//待测试对象@BeforeEachpublicvoidsetUp(){MockitoAnnotations.openMocks(this);//初始化Mockito模拟对象calculatorService=newCalculatorService(mockDatabaseService);//使用模拟对象实例化待测试类}@TestpublicvoidtestCalculateResultFound(){//准备输入和期望输出intid=1;Map<String,Object>record=newHashMap<>();record.put("value1",10);record.put("value2",20);intexpectedSum=30;StringexpectedResult="Sum:"+expectedSum;//配置模拟对象的行为when(mockDatabaseService.findRecordById(id)).thenReturn(record);//调用待测试方法StringactualResult=calculatorService.calculateResult(id);//验证结果assertEquals(expectedResult,actualResult);//验证是否按预期调用了模拟对象的方法verify(mockDatabaseService).findRecordById(id);}@TestpublicvoidtestCalculateResultNotFound(){//准备输入和期望输出intid=2;StringexpectedResult="RecordNotFound";//配置模拟对象的行为when(mockDatabaseService.findRecordById(id)).thenReturn(null);//调用待测试方法StringactualResult=calculatorService.calculateResult(id);//验证结果assertEquals(expectedResult,actualResult);//验证是否按预期调用了模拟对象的方法verify(mockDatabaseService).findRecordById(id);}}```解析思路:*Mockito初始化:使用`@Mock`注解创建`DatabaseService`的模拟对象`mockDatabaseService`。在`setUp()`方法中,调用`MockitoAnnotations.openMocks(this)`来初始化所有被`@Mock`注解的模拟对象。然后,使用这个模拟对象来构造`CalculatorService`实例。*测试方法:编写两个`@Test`注解的测试方法,分别对应两种场景(找到记录和找不到记录)。*配置模拟行为(Stubbing):在`testCalculateResultFound`中,使用`when(...).thenReturn(...)`配置`mockDatabaseService.findRecordById(1)`在被调用时返回预设的记录Map。在`testCalculateResultNotFound`中,配置其返回`null`。*执行测试方法:调用`calculatorService.calculateResult(id)`方法,传入测试数据。*验证结果(Assertion):使用`assertEquals`验证方法返回的实际结果是否与预期结果一致。*验证行为(Verification):使用`verify(mockDatabaseService).findRecordById(id)`来确认`findRecordById`方法是否确实被调用了一次(使用`verify()`默认的次数检查,即至少一次)。2.(30分)```javaimportorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;importorg.springframework.boot.test.context.SpringBootTest;importorg.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureTestDatabase;importorg.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;importorg.springframework.test.web.servlet.MockMvc;importorg.springframework.test.web.servlet.request.MockMvcRequestBuilders;importorg.springframework.test.web.servlet.result.MockMvcResultMatchers;importstaticorg.springframework.test.web.servlet.result.MockMvcResultMatchers.status;@SpringBootTest@AutoConfigureMockMvc//自动配置MockMvc@AutoConfigureTestDatabase(replace=AutoConfigureTestDatabase.Replace.NONE)//使用真实的数据库配置,或者设置为InMemory使用内存数据库publicclassUserControllerTest{@AutowiredprivateMockMvcmockMvc;//自动注入MockMvc@AutowiredprivateTestEntityManagertestEntityManager;//自动注入TestEntityManager,用于设置测试数据@TestpublicvoidtestGetUserFound()throwsException{//设置测试数据(如果TestEntityManager可用,或者数据已通过其他方式准备好)//例如:testEntityManager.persist(newUser("user1","Alice"));//如果User类有ID等字段//发送GET请求并验证响应mockMvc.perform(MockMvcRequestBuilders.get("/users/user1")).andExpect(status().isOk())//验证HTTP状态码.andExpect(MockMvcResultMatchers.content().string("Useruser1:Alice"));//验证响应内容}@TestpublicvoidtestGetUserNotFound()throwsException{//发送GET请求并验证响应mockMvc.perform(MockMvcRequestBuilders.get("/users/u

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论