网站证书怎么做广州做营销型网站建设

张小明 2026/1/13 7:14:50
网站证书怎么做,广州做营销型网站建设,中国招标网官网首页,建设工程信息化平台Mockito 单元测试框架实战一、Mockito 简介 Mockito 是 Java 生态中最流行的 Mock 框架#xff0c;被广泛应用于单元测试中。它提供了简洁优雅的 API#xff0c;帮助开发者轻松创建和配置 Mock 对象#xff0c;从而实现对依赖项的隔离测试。 1.1 为什么需要 Mock#xff1f…Mockito 单元测试框架实战一、Mockito 简介Mockito 是 Java 生态中最流行的 Mock 框架被广泛应用于单元测试中。它提供了简洁优雅的 API帮助开发者轻松创建和配置 Mock 对象从而实现对依赖项的隔离测试。1.1 为什么需要 Mock在实际开发中我们常常遇到以下场景依赖的外部服务数据库、HTTP API难以在测试环境搭建某些依赖执行缓慢影响测试效率需要模拟各种异常情况进行测试希望独立测试某个模块不受其他模块影响Mockito 正是为解决这些问题而生它可以创建虚拟对象替代真实依赖让测试变得简单高效。1.2 Mockito 的核心优势简洁的 API使用流畅的链式调用代码可读性强强大的验证功能可以验证方法调用次数、参数等灵活的参数匹配支持精确匹配、类型匹配、自定义匹配注解支持通过注解简化 Mock 对象的创建与主流框架集成完美支持 JUnit、Spring Boot 等二、Mockito 核心架构Mockito 的架构分为四个主要层次测试代码层我们编写的测试代码Mockito API提供 mock()、when()、verify() 等核心方法Mock 对象代理动态创建的代理对象字节码增强底层使用 ByteBuddy 进行字节码操作三、快速开始3.1 添加依赖在项目中添加 Mockito 依赖!-- Maven --dependencygroupIdorg.mockito/groupIdartifactIdmockito-core/artifactIdversion5.8.0/versionscopetest/scope/dependency!-- 如果使用 JUnit 5 --dependencygroupIdorg.mockito/groupIdartifactIdmockito-junit-jupiter/artifactIdversion5.8.0/versionscopetest/scope/dependency// Gradle testImplementation org.mockito:mockito-core:5.8.0 testImplementation org.mockito:mockito-junit-jupiter:5.8.03.2 基本用法三步曲Mockito 的基本使用可以归纳为三个步骤步骤 1创建 Mock 对象importstaticorg.mockito.Mockito.*;// 方式一使用 mock() 方法ListStringmockListmock(List.class);// 方式二使用 Mock 注解MockprivateUserRepositoryuserRepository;步骤 2定义 Mock 行为// 定义返回值when(mockList.get(0)).thenReturn(first);when(mockList.size()).thenReturn(10);// 定义异常when(mockList.get(1)).thenThrow(newRuntimeException(出错了));// 链式调用when(mockList.isEmpty()).thenReturn(false).thenReturn(true);// 第二次调用返回 true步骤 3验证方法调用// 验证方法被调用verify(mockList).add(item);// 验证调用次数verify(mockList,times(2)).add(anyString());// 验证从未调用verify(mockList,never()).clear();四、验证方法详解Mockito 提供了丰富的验证方法来检查 Mock 对象的交互4.1 调用次数验证importstaticorg.mockito.Mockito.*;TestpublicvoidtestVerification(){ListStringmockListmock(List.class);mockList.add(once);mockList.add(twice);mockList.add(twice);// 验证调用 1 次默认verify(mockList).add(once);// 验证调用 2 次verify(mockList,times(2)).add(twice);// 验证从未调用verify(mockList,never()).clear();// 验证至少调用 1 次verify(mockList,atLeastOnce()).add(anyString());// 验证至少调用 2 次verify(mockList,atLeast(2)).add(twice);// 验证最多调用 5 次verify(mockList,atMost(5)).add(anyString());}4.2 调用顺序验证TestpublicvoidtestInOrder(){ListStringfirstMockmock(List.class);ListStringsecondMockmock(List.class);firstMock.add(first);secondMock.add(second);firstMock.add(third);// 验证调用顺序InOrderinOrderinOrder(firstMock,secondMock);inOrder.verify(firstMock).add(first);inOrder.verify(secondMock).add(second);inOrder.verify(firstMock).add(third);}4.3 超时验证TestpublicvoidtestTimeout(){ListStringmockListmock(List.class);// 异步调用newThread(()-{try{Thread.sleep(100);mockList.add(async);}catch(InterruptedExceptione){e.printStackTrace();}}).start();// 验证在 200ms 内被调用verify(mockList,timeout(200)).add(async);}五、参数匹配器参数匹配器ArgumentMatchers让我们可以灵活地匹配方法参数。5.1 常用匹配器importstaticorg.mockito.ArgumentMatchers.*;TestpublicvoidtestMatchers(){MapString,StringmockMapmock(Map.class);// any() - 匹配任何对象when(mockMap.get(any())).thenReturn(value);// anyString() - 匹配任何字符串when(mockMap.put(anyString(),anyString())).thenReturn(old);// anyInt() - 匹配任何整数when(mockMap.remove(anyInt())).thenReturn(removed);// eq() - 精确匹配when(mockMap.get(eq(key))).thenReturn(specific);// isNull() - 匹配 nullwhen(mockMap.get(isNull())).thenReturn(null-value);// isNotNull() - 匹配非 nullwhen(mockMap.containsKey(isNotNull())).thenReturn(true);}5.2 自定义匹配器TestpublicvoidtestCustomMatcher(){ListStringmockListmock(List.class);// 使用 argThat 自定义匹配逻辑when(mockList.add(argThat(s-s.length()5))).thenReturn(true);assertTrue(mockList.add(long string));// trueassertFalse(mockList.add(short));// false}5.3 混合使用注意事项// ❌ 错误不能混用匹配器和具体值when(mockMap.put(anyString(),value)).thenReturn(old);// ✅ 正确全部使用匹配器when(mockMap.put(anyString(),eq(value))).thenReturn(old);六、高级特性6.1 使用注解简化代码Mockito 提供了多个注解来简化 Mock 对象的创建和注入importorg.mockito.Mock;importorg.mockito.InjectMocks;importorg.mockito.junit.jupiter.MockitoExtension;importorg.junit.jupiter.api.extension.ExtendWith;ExtendWith(MockitoExtension.class)publicclassUserServiceTest{// Mock 创建 Mock 对象MockprivateUserRepositoryuserRepository;MockprivateEmailServiceemailService;// InjectMocks 自动注入 Mock 依赖InjectMocksprivateUserServiceuserService;TestpublicvoidtestCreateUser(){UserusernewUser(张三,zhangexample.com);when(userRepository.save(any(User.class))).thenReturn(user);UsercreateduserService.createUser(user);verify(userRepository).save(user);verify(emailService).sendWelcomeEmail(user.getEmail());assertEquals(张三,created.getName());}}6.2 Spy - 部分 MockSpy 允许我们监视真实对象只 Mock 部分方法TestpublicvoidtestSpy(){ListStringrealListnewArrayList();ListStringspyListspy(realList);// 真实方法会被调用spyList.add(one);spyList.add(two);// Mock 特定方法when(spyList.size()).thenReturn(100);assertEquals(100,spyList.size());// Mock 的行为assertEquals(one,spyList.get(0));// 真实的行为}实际应用场景publicclassOrderService{publicdoublecalculateTotal(Orderorder){doublesubtotalcalculateSubtotal(order);doubletaxcalculateTax(subtotal);returnsubtotaltax;}protecteddoublecalculateSubtotal(Orderorder){// 复杂的计算逻辑returnorder.getItems().stream().mapToDouble(Item::getPrice).sum();}protecteddoublecalculateTax(doubleamount){returnamount*0.1;}}TestpublicvoidtestCalculateTotal(){OrderServiceorderServicespy(newOrderService());// 只 Mock calculateTax 方法doReturn(50.0).when(orderService).calculateTax(anyDouble());OrderordernewOrder();order.addItem(newItem(商品,100.0));doubletotalorderService.calculateTotal(order);assertEquals(150.0,total);// 100 50}6.3 Answer - 自定义返回逻辑Answer 接口允许我们实现复杂的返回逻辑TestpublicvoidtestAnswer(){ListStringmockListmock(List.class);// 根据参数动态返回结果when(mockList.get(anyInt())).thenAnswer(invocation-{Integerindexinvocation.getArgument(0);returnelement-index;});assertEquals(element-0,mockList.get(0));assertEquals(element-5,mockList.get(5));}实际应用场景 - 模拟异步回调publicinterfaceAsyncService{voidexecuteAsync(Stringtask,Callbackcallback);}TestpublicvoidtestAsyncCallback(){AsyncServiceasyncServicemock(AsyncService.class);doAnswer(invocation-{Stringtaskinvocation.getArgument(0);Callbackcallbackinvocation.getArgument(1);// 模拟异步执行后调用回调callback.onSuccess(完成: task);returnnull;}).when(asyncService).executeAsync(anyString(),any(Callback.class));CallbackmockCallbackmock(Callback.class);asyncService.executeAsync(任务1,mockCallback);verify(mockCallback).onSuccess(完成: 任务1);}6.4 ArgumentCaptor - 捕获参数ArgumentCaptor 用于捕获传递给 Mock 方法的参数便于后续断言TestpublicvoidtestArgumentCaptor(){ListStringmockListmock(List.class);mockList.add(John);mockList.add(Jane);// 创建 ArgumentCaptorArgumentCaptorStringcaptorArgumentCaptor.forClass(String.class);// 捕获所有调用的参数verify(mockList,times(2)).add(captor.capture());ListStringcapturedValuescaptor.getAllValues();assertEquals(Arrays.asList(John,Jane),capturedValues);}实际应用场景 - 验证复杂对象TestpublicvoidtestCaptureComplexObject(){UserRepositoryuserRepositorymock(UserRepository.class);UserServiceuserServicenewUserService(userRepository);userService.registerUser(张三,zhangexample.com,25);// 捕获传递给 save 方法的 User 对象ArgumentCaptorUseruserCaptorArgumentCaptor.forClass(User.class);verify(userRepository).save(userCaptor.capture());UsercapturedUseruserCaptor.getValue();assertEquals(张三,capturedUser.getName());assertEquals(zhangexample.com,capturedUser.getEmail());assertEquals(25,capturedUser.getAge());assertNotNull(capturedUser.getCreatedAt());}七、Spring Boot 集成实战在实际项目中Mockito 最常见的应用场景是测试 Spring Boot 应用。7.1 依赖配置Spring Boot 项目通常已经包含 Mockito但建议显式添加dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency7.2 Service 层测试被测试的 ServiceServicepublicclassOrderService{privatefinalOrderRepositoryorderRepository;privatefinalInventoryServiceinventoryService;privatefinalPaymentServicepaymentService;privatefinalNotificationServicenotificationService;AutowiredpublicOrderService(OrderRepositoryorderRepository,InventoryServiceinventoryService,PaymentServicepaymentService,NotificationServicenotificationService){this.orderRepositoryorderRepository;this.inventoryServiceinventoryService;this.paymentServicepaymentService;this.notificationServicenotificationService;}publicOrdercreateOrder(OrderRequestrequest){// 1. 检查库存if(!inventoryService.checkStock(request.getProductId(),request.getQuantity())){thrownewInsufficientStockException(库存不足);}// 2. 创建订单OrderordernewOrder();order.setProductId(request.getProductId());order.setQuantity(request.getQuantity());order.setUserId(request.getUserId());order.setStatus(OrderStatus.PENDING);order.setCreatedAt(LocalDateTime.now());OrdersavedOrderorderRepository.save(order);// 3. 扣减库存inventoryService.decreaseStock(request.getProductId(),request.getQuantity());// 4. 处理支付PaymentResultpaymentResultpaymentService.processPayment(savedOrder.getId(),request.getPaymentMethod(),calculateAmount(request));if(paymentResult.isSuccess()){savedOrder.setStatus(OrderStatus.PAID);orderRepository.save(savedOrder);// 5. 发送通知notificationService.sendOrderConfirmation(savedOrder);}else{// 回滚库存inventoryService.increaseStock(request.getProductId(),request.getQuantity());savedOrder.setStatus(OrderStatus.FAILED);}returnsavedOrder;}privateBigDecimalcalculateAmount(OrderRequestrequest){// 计算金额逻辑returnBigDecimal.valueOf(request.getQuantity()*100);}}测试类ExtendWith(MockitoExtension.class)publicclassOrderServiceTest{MockprivateOrderRepositoryorderRepository;MockprivateInventoryServiceinventoryService;MockprivatePaymentServicepaymentService;MockprivateNotificationServicenotificationService;InjectMocksprivateOrderServiceorderService;privateOrderRequestorderRequest;BeforeEachvoidsetUp(){orderRequestnewOrderRequest();orderRequest.setProductId(1L);orderRequest.setQuantity(2);orderRequest.setUserId(100L);orderRequest.setPaymentMethod(CREDIT_CARD);}TestDisplayName(成功创建订单)voidtestCreateOrder_Success(){// Givenwhen(inventoryService.checkStock(1L,2)).thenReturn(true);OrdermockOrdernewOrder();mockOrder.setId(1L);mockOrder.setStatus(OrderStatus.PENDING);when(orderRepository.save(any(Order.class))).thenReturn(mockOrder);PaymentResultpaymentResultnewPaymentResult(true,SUCCESS);when(paymentService.processPayment(anyLong(),anyString(),any(BigDecimal.class))).thenReturn(paymentResult);// WhenOrderresultorderService.createOrder(orderRequest);// ThenassertNotNull(result);assertEquals(OrderStatus.PAID,result.getStatus());// 验证交互verify(inventoryService).checkStock(1L,2);verify(inventoryService).decreaseStock(1L,2);verify(orderRepository,times(2)).save(any(Order.class));verify(paymentService).processPayment(eq(1L),eq(CREDIT_CARD),any(BigDecimal.class));verify(notificationService).sendOrderConfirmation(result);}TestDisplayName(库存不足时抛出异常)voidtestCreateOrder_InsufficientStock(){// Givenwhen(inventoryService.checkStock(1L,2)).thenReturn(false);// When ThenassertThrows(InsufficientStockException.class,()-{orderService.createOrder(orderRequest);});// 验证不会调用后续方法verify(inventoryService).checkStock(1L,2);verify(inventoryService,never()).decreaseStock(anyLong(),anyInt());verify(orderRepository,never()).save(any(Order.class));verify(paymentService,never()).processPayment(anyLong(),anyString(),any(BigDecimal.class));}TestDisplayName(支付失败时回滚库存)voidtestCreateOrder_PaymentFailed(){// Givenwhen(inventoryService.checkStock(1L,2)).thenReturn(true);OrdermockOrdernewOrder();mockOrder.setId(1L);when(orderRepository.save(any(Order.class))).thenReturn(mockOrder);PaymentResultpaymentResultnewPaymentResult(false,INSUFFICIENT_FUNDS);when(paymentService.processPayment(anyLong(),anyString(),any(BigDecimal.class))).thenReturn(paymentResult);// WhenOrderresultorderService.createOrder(orderRequest);// ThenassertEquals(OrderStatus.FAILED,result.getStatus());// 验证回滚库存verify(inventoryService).decreaseStock(1L,2);verify(inventoryService).increaseStock(1L,2);verify(notificationService,never()).sendOrderConfirmation(any(Order.class));}}7.3 Controller 层测试RestControllerRequestMapping(/api/orders)publicclassOrderController{AutowiredprivateOrderServiceorderService;PostMappingpublicResponseEntityOrderResponsecreateOrder(RequestBodyOrderRequestrequest){OrderorderorderService.createOrder(request);returnResponseEntity.ok(newOrderResponse(order));}}// 测试类WebMvcTest(OrderController.class)classOrderControllerTest{AutowiredprivateMockMvcmockMvc;MockBeanprivateOrderServiceorderService;TestDisplayName(POST /api/orders - 成功创建订单)voidtestCreateOrder()throwsException{// GivenOrderRequestrequestnewOrderRequest();request.setProductId(1L);request.setQuantity(2);OrdermockOrdernewOrder();mockOrder.setId(1L);mockOrder.setStatus(OrderStatus.PAID);when(orderService.createOrder(any(OrderRequest.class))).thenReturn(mockOrder);// When ThenmockMvc.perform(post(/api/orders).contentType(MediaType.APPLICATION_JSON).content({\productId\:1,\quantity\:2})).andExpect(status().isOk()).andExpect(jsonPath($.id).value(1)).andExpect(jsonPath($.status).value(PAID));verify(orderService).createOrder(any(OrderRequest.class));}}八、最佳实践8.1 优先 Mock 接口而非具体类// ✅ 推荐Mock 接口UserRepositoryuserRepositorymock(UserRepository.class);// ❌ 不推荐Mock 具体类可能遇到 final 方法问题UserRepositoryImpluserRepositorymock(UserRepositoryImpl.class);8.2 避免过度 Mock// ❌ 过度 Mock - 测试变得脆弱TestvoidbadTest(){when(dependency1.method1()).thenReturn(value1);when(dependency2.method2()).thenReturn(value2);when(dependency3.method3()).thenReturn(value3);// ... 大量的 Mock 设置// 实际业务逻辑被淹没service.doSomething();// 验证大量细节verify(dependency1,times(2)).method1();verify(dependency2).method2();// ...}// ✅ 适度 Mock - 只关注核心交互TestvoidgoodTest(){// 只 Mock 必要的依赖when(userRepository.findById(1L)).thenReturn(Optional.of(testUser));UserresultuserService.getUser(1L);assertEquals(张三,result.getName());verify(userRepository).findById(1L);}8.3 使用 InjectMocks 自动注入// ✅ 推荐使用注解自动注入MockprivateUserRepositoryuserRepository;InjectMocksprivateUserServiceuserService;// ❌ 不推荐手动创建容易出错且繁琐UserServiceuserServicenewUserService(userRepository,emailService,...);8.4 合理使用 ArgumentCaptor// ✅ 推荐验证复杂对象的属性ArgumentCaptorUsercaptorArgumentCaptor.forClass(User.class);verify(userRepository).save(captor.capture());assertEquals(张三,captor.getValue().getName());// ❌ 不推荐简单参数使用 Captor直接匹配即可ArgumentCaptorStringcaptorArgumentCaptor.forClass(String.class);verify(service).process(captor.capture());assertEquals(value,captor.getValue());// 直接用 eq(value) 更简洁8.5 验证重要交互忽略次要细节// ✅ 推荐只验证核心业务逻辑TestvoidtestUserRegistration(){userService.register(user);verify(userRepository).save(user);// 核心保存用户verify(emailService).sendWelcome(user.getEmail());// 核心发送邮件// 不验证日志记录等次要操作}// ❌ 不推荐验证过多细节verify(logger).info(开始注册用户);verify(validator).validate(user);verify(logger).debug(用户验证通过);// ... 测试变得脆弱8.6 使用有意义的测试数据// ✅ 推荐清晰的测试数据UsertestUsernewUser(张三,zhangexample.com,25);// ❌ 不推荐无意义的数据UsertestUsernewUser(test,testtest.com,0);8.7 一个测试方法只测一个场景// ✅ 推荐分离测试场景TestvoidtestCreateUser_Success(){// 测试成功场景}TestvoidtestCreateUser_DuplicateEmail(){// 测试邮箱重复场景}TestvoidtestCreateUser_InvalidInput(){// 测试无效输入场景}// ❌ 不推荐在一个测试中测试多个场景TestvoidtestCreateUser(){// 成功场景// 失败场景// 异常场景// ... 难以定位问题}九、总结Mockito 是 Java 单元测试的利器掌握它可以显著提升测试质量和开发效率。希望这篇文章能帮助你更好地使用 Mockito写出高质量的单元测试
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

阜阳市重点工程建设局网站载网站源码 怎么下载不了

跨学科写作最大的坑,不是懂得少,而是把两个领域的知识,硬生生“粘”在一起。好写作AI要做的,是帮你找到它们之间真正的“接口”。好写作AI官方网址:https://www.haoxiezuo.cn/一、痛点诊断:你的跨学科论文&…

张小明 2026/1/13 2:18:41 网站建设

网站开发员爱空间装修公司口碑怎么样

前言 中望 CAD2026 机械版是一款国产专业机械设计软件,功能齐全、上手简单,专门用于绘制机械图纸、零件装配和输出生产图纸,新老用户都能快速上手出活,还支持兼容旧图纸、管理产品数据,性价比突出。 一、机械设计超省…

张小明 2026/1/5 5:10:01 网站建设

交互式网站和非交互式网站营销和推广的区别

在数字化转型与信创替代双重浪潮下,企业IT架构日益复杂,传统监控工具已难以应对海量数据与动态业务需求。智能运维(AIOps)平台可以实现从“被动响应”到“主动预测”的运维模式变革,成为企业提升运维效率、保障业务稳定…

张小明 2026/1/5 5:09:29 网站建设

网站建设技术支持杭州 洛阳网站建设公司 网络服务

小白羊网盘是一款基于阿里云盘Open平台API开发的免费开源第三方客户端,为阿里云盘用户提供了更加便捷高效的文件管理体验。作为阿里云盘第三方客户端的优秀代表,它支持Windows、macOS和Linux三大操作系统,解决了传统网盘客户端的诸多使用痛点…

张小明 2026/1/10 11:43:47 网站建设

住房和创新建设部网站阿里云服务器 网站模板

Elasticsearch容灾备份实战:从原理到恢复的完整指南你有没有遇到过这样的场景?凌晨两点,监控告警突然炸响——某个关键索引被误删,日志数据正在丢失。或者更糟:整个可用区断电,生产集群彻底不可用。这时候&…

张小明 2026/1/6 7:14:33 网站建设

做网站用什么空间好网站怎么利用朋友圈做推广

21.3 业务导向评测:构建贴合实际场景的评估体系 课程概述 在上一节课中,我们学习了模型评测的三个核心维度:通用评测、场景化评测和安全策略。本节课我们将深入探讨如何构建业务导向的评测体系,重点关注如何根据具体的业务需求和场景特点,设计贴合实际应用场景的评估方案…

张小明 2026/1/5 5:07:52 网站建设