当前位置: 首页 > news >正文

android获取Wordpress数据库优化关键词的步骤

android获取Wordpress数据库,优化关键词的步骤,郑州seo管理,比较好的网站开发教学网站前言 当我是1个3年初级程序员时#xff0c; 我被面试者问到1个问题#xff1a; 如何保证你的开发任务交付质量 当我是1个7年开发组长时#xff0c; 我被面试者问到另1个问题#xff1a;如何保证你的团队的代码质量#xff0c; 减少rework。 又若干年后#xff0c; 我才… 前言 当我是1个3年初级程序员时 我被面试者问到1个问题 如何保证你的开发任务交付质量 当我是1个7年开发组长时 我被面试者问到另1个问题如何保证你的团队的代码质量 减少rework。 又若干年后 我才明白当年我的回答是多么的傻嗨 什么理解业务 勤沟通 代码review流程都是废话。 真正的核心是测试 足够的单元测试 当你的下属提交pr时顺便把 一份coverage 达到80% 的Junit testing report 放上jira, 你还不信任他这次任务的代码质量吗 但是提高Junit 的覆盖率并不简单 很多当前项目上的依赖 这时 我们就是需要Mockito了 什么是Mockito Mockito 是一个流行的 Java 单元测试框架用于模拟和验证对象的行为。它提供了一组简单易用的 API使得在编写单元测试时可以轻松地创建和控制模拟对象以便在测试中隔离依赖项和验证对象的行为。 Mockito 的主要特点包括 简单易用的 APIMockito 提供了一组简单易用的 API使得在编写单元测试时可以轻松地创建和控制模拟对象。 模拟任意对象的行为Mockito 可以模拟任意对象的行为包括静态方法、私有方法和 final 方法等。 验证对象的行为Mockito 提供了一组 API 来验证对象的行为例如验证方法是否被调用、验证方法的参数是否正确等。 支持多种测试框架Mockito 可以与多种测试框架一起使用如 JUnit、TestNG 等。 强大的功能Mockito 提供了一些强大的功能如模拟方法的返回值、模拟方法的异常抛出、模拟方法的调用次数等。 Mockito 广泛应用于 Java 开发中被广泛认为是 Java 单元测试中最流行和最强大的框架之一。它提供了一种简单而强大的方式来编写单元测试并且在测试中隔离依赖项和验证对象的行为。 为什么需要Mockito 简单来讲 Mockito 可以模拟1个类的对象 并强制指定or 改变这个对象的行为 例如 类A的方法a() 返回 当前日期的String “20241001” 但是 我们可以mock 1个对象 aMock 并指定aMock.a() 返回 “20000101” 这样 当我们的测试调用了aMock.a() 它真的会返回20000101 这不是脱裤子放屁吗 实际上 既然我们mock了A类 我们想要测试的并不是A类的代码 而是另个调用了A类的类的代码 (B 具有1个A对象的成员) 例如 类B 的b() 方法 调用了 aObj.a() (aObj 是 类A的对象) 当我们测试类B() 时 可以mock掉A, 并随时改变a() 方法的行为, 并测试不同a()返回值下 B的行为是否正确 一个具体场景 上面还是说的太绕了 举个例子 例如我有1个Service 类 OrderService: OrderService.java Service Slf4j public class OrderService {Autowiredprivate OrderDao orderDao;// this method is used to query order by idpublic Order queryById(Long id) {// if optional.isPresent() is false, it will throw NoSuchElementExceptionreturn orderDao.findById(id).orElseThrow(() - new NoSuchElementException(No such order by id: id));}public Order updateOrder(Long orderId, Order orderDetails) {Order order null;try{order this.queryById(orderId);} catch (NoSuchElementException e) {log.error(Error in getting order by id..., e);throw e;} catch (QueryTimeoutException e) {log.error(timeout.., e);return null;}order.setCommodityName(orderDetails.getCommodityName());order.setPrice(orderDetails.getPrice());return orderDao.save(order);}public Order createOrder(Order order) {return orderDao.save(order);}public void deleteOrder(Long orderId) {orderDao.deleteById(orderId);} }其中该类调用了Dao类 OrderDao, 而OrderDao是直接与数据交互的 如果我们正常编写UT, 与数据真是交互 编写1个for updateOrder()的测试方法 OrderServiceIntrusiveTest.java SpringBootTest ActiveProfiles(dev) class OrderServiceIntrusiveTest {Autowiredprivate OrderService orderService;Testvoid updateOrder() {Order order Order.builder().commodityName(ASUS ROG ZEPHYRUS).price(3L).userId(3L).build();order orderService.createOrder(order);Order orderUpdated Order.builder().commodityName(ASUS ROG ZEPHYRUS V3).price(4L).build();orderUpdated orderService.updateOrder(order.getId(), orderUpdated);assertEquals(ASUS ROG ZEPHYRUS V3, orderUpdated.getCommodityName());assertEquals(4L, orderUpdated.getPrice());orderService.deleteOrder(order.getId());} }这个case 能正常执行 但是有下面若干缺点 依赖dev env的db 环境 如果dev env 出问题 测试就failed了必须启动springboot 容器 执行时间偏长 特别是多个测试类的情况下为了让测试可重复执行 测试完之后必须清理数据覆盖率低 难以cover exception 处理场景 上红色条标记的代码都是未有cover的 至于怎么测试 Timeout 场景下业务代码 难道还要测试中拔网线吗 如果Exception 场景无法测试 只测试了happyflow, 如何让你的技术经理放心的你的交付呢 而Mockito 可以解决这些问题. 构建Mock对象 从这里开始我们拆解Mockito的各个方法使用要点 首先引入mockito 依赖 !-- mockito --dependencygroupIdorg.mockito/groupIdartifactIdmockito-core/artifactIdversion5.7.0/versionscopetest/scope/dependency使用Mockito.mock() public class BuildMockObjTest {Testvoid testBuildMockObj() {StringUtil1 util Mockito.mock(StringUtil1.class);String str util.formatString(test);assertNull(str); // should be null} }class StringUtil1 {public String formatString(String str) {return str : LocalDate.now().toString();} }这例子中 我们先写了1个 StringUtil1类 它有1个方法可以为1个String 添加日期suffix 我们可以用Mockito.mock方法构建1个mock 的StringUtil 对象 这个mock对象创建后里面的所有方法都是未知空位 等待我们的指定 所以当我们直接调用 String str util.formatString(“test”); 时 其实并没有调用真正 formatString()里的代码 返回的是null 使用Mock 注解 下面写法与上面是等价的 在项目中使用注解更加常见 注意的事测试类本身需要 ExtendWith(MockitoExtension.class) 注解 ExtendWith(MockitoExtension.class) public class BuildMockObjWithAnnotationTest {Mockprivate StringUtil1 util;Testvoid testBuildMockObj() {String str util.formatString(test);assertNull(str); // should be null} }打桩 (Stub) 什么是打桩Stub与断言 先说下什么是打桩 Mockito 的核心 概念就是打桩和断言 其中打桩是Mockito 特有的行为 简单来讲打桩就是指定 mock 对象的方法行为 举个例子 我令 dao 方法正常返回 那么service 的update() 方法输出1 我令 dao 方法timeout, 那么service 的update()应该10秒后爆出异常 上面的令 某个mock方法 执行某种行为的本身 就是打桩 后面的那么 就是断言 如果update()的行为并不是断言描述的情况 我们认为测试不通过 需要开发人员检查业务代码。 断言就是所谓的Assert了 这个与mockito没关 任何UT 都应该包含至少一个断言 Stub 修改方法的返回逻辑 when().thenReturn() thenReturn 可以直接修改1个对象方法的输出逻辑 例如 ExtendWith(MockitoExtension.class) Slf4j public class StubTest {Mockprivate StringUtil3 mockUtil;Testvoid testStubReturn() {Mockito.when(mockUtil.formatString(Mockito.any(String.class))).thenReturn(test: LocalDateTime.now().toString());String str mockUtil.formatString(test);log.info(str: {}, str);assertNotNull(str);}}class StringUtil3 {public String formatString(String str) {return str : LocalDate.now().toString();} }原本方法是 输出 参数 日期 但是thenReturn 直接修改为 “test 日期时间, 注意这里的test 是hardcode的 输出 10:13:31.827 [main] INFO com.home.javacommon.mockito.StubTest -- str: test: 2024-09-28T10:13:31.816733893DoReturn().when() 这是另1风格写法 Testvoid testStubReturn2() {Mockito.doReturn(test: LocalDateTime.now().toString()).when(mockUtil).formatString(Mockito.any(String.class));String str mockUtil.formatString(test);log.info(str: {}, str);assertNotNull(str);}注意这里when() 后值 而when()参数是1个mock对象 而不是mork对象带方法 given().willReturn() 这里是BDD 写法 我更prefer 这种 void testStubReturn3() {given(mockUtil.formatString(Mockito.any(String.class))).willReturn(test: LocalDateTime.now().toString());String str mockUtil.formatString(test);log.info(str: {}, str);assertNotNull(str);}效果也是一样的 Stub 令对象方法抛出异常 when().thenThrow() 例子 Testvoid testStubThrow() {Mockito.when(mockUtil.formatString(Mockito.any(String.class))).thenThrow(new UnsupportedOperationException());String str null;assertThrows(UnsupportedOperationException.class, () - mockUtil.formatString(test));}值得注意是 Mock对象的方法定义如果没有throws 1个 CheckedException的话 不能打桩让Mock对象抛出这个CheckException的 这里的例子是让其抛出1个RuntimeException doThrow().when() Testvoid testStubThrow2() {Mockito.doThrow(new UnsupportedOperationException()).when(mockUtil).formatString(Mockito.any(String.class));String str null;assertThrows(UnsupportedOperationException.class, () - mockUtil.formatString(test));}given().willThrow() Testvoid testStubThrow3() {given(mockUtil.formatString(Mockito.any(String.class))).willThrow(new UnsupportedOperationException());String str null;assertThrows(UnsupportedOperationException.class, () - mockUtil.formatString(test));}Stub 灵活地令对象方法执行指定行为 例如 如果我想让方法返回其第1和第2个参数的合并字符串 而上面的Return 方式是无法获取参数的值的 when().thenAnswer() 例子 ExtendWith(MockitoExtension.class) Slf4j public class StubAnswerTest {Mockprivate StringUtil4 mockUtil;/** invocation is a concept of the mockito invocation, it includes the context information of the mock* e.g. the argument of the method, return values** usually, you can use the argument(0) to get the first argument** some methods* getArgument(int index): get the argument at index* getArguments(): get all arguments* getMethod(): get the method* getMock(): get the mock object*/Testvoid testStubAnswer() {Mockito.when(mockUtil.formatString(Mockito.any(String.class), Mockito.any(String.class))).thenAnswer((invocation) - invocation.getArgument(0) : invocation.getArgument(1));String str mockUtil.formatString(test, test2);assertEquals(test:test2, str);} }class StringUtil4 {public String formatString(String str1, String str2) {return its hard coded;} }值得注意的是 invocation的使用 参考上面的注解 doAnswer().when() 另1个写法 Testvoid testStubAnswer2() {Mockito.doAnswer((invocation) - invocation.getArgument(0) : invocation.getArgument(1)).when(mockUtil).formatString(Mockito.any(String.class), Mockito.any(String.class));String str mockUtil.formatString(test, test2);assertEquals(test:test2, str);}given().willAnswer() BDD 风格 Testvoid testStubAnswer3() {given(mockUtil.formatString(Mockito.any(String.class), Mockito.any(String.class))).willAnswer((invocation) - invocation.getArgument(0) : invocation.getArgument(1));String str mockUtil.formatString(test, test2);assertEquals(test:test2, str);}Stub 调用真实的方法 有一种场景 1个Mock 对象里有若干个方法 但是Mock出来后 所有的方法的行为都是空的 但是Mockito 提供了CallRealMethod 功能 让我们可以让其中某个(or 若干个) 方法使用真实定义的逻辑 when().thenCallRealMethod() 下面的例子 Mock对象里有两个方法 而我们只打桩了 第2个让其执行真实定义的代码 所以第一个方法输出是null 第2个方法正常输出 ExtendWith(MockitoExtension.class) public class StubCallRealMethodTest {Mockprivate StringUtil5 mockUtil;Testvoid testStubCallRealMethod() {Mockito.when(mockUtil.formatString(Mockito.any(String.class), Mockito.any(String.class))).thenCallRealMethod();String str mockUtil.formatString(test);assertNull(str);str mockUtil.formatString(test, test2);assertEquals(test:test2, str);} }class StringUtil5 {public String formatString(String str) {return str : LocalDate.now().toString();}public String formatString(String str1, String str2) {return str1 : str2;} }DoCallRealMethod().when() 另一种写法 Testvoid testStubCallRealMethod2() {Mockito.doCallRealMethod().when(mockUtil).formatString(Mockito.any(String.class), Mockito.any(String.class));String str mockUtil.formatString(test);assertNull(str);}given().willCallRealMethod() BDD 风格 Testvoid testStubCallRealMethod3() {given(mockUtil.formatString(Mockito.any(String.class), Mockito.any(String.class))).willCallRealMethod();String str mockUtil.formatString(test);assertNull(str);str mockUtil.formatString(test, test2);assertEquals(test:test2, str);}Stub 让无返回值 void 对象方法不抛出任何异常 DoNothing 如果只是让 方法不抛出异常 例如Mock 1个 Dao对象的 void sqlExec() 方法。 实际上就是让它 不做任何事情 而 when().then() 和 given().will() 都不适用于 mock1个无返回值方法的 这时我们只能用DoNothing doNothing().when() 例子 ExtendWith(MockitoExtension.class) Slf4j public class StubTest {Mockprivate StringUtil3 mockUtil;Testvoid testStubNotThrow() {Mockito.doNothing().when(mockUtil).formatString2(Mockito.any(String.class));assertDoesNotThrow(() - mockUtil.formatString2(test));}}class StringUtil3 {public void formatString2(String str) {throw new UnsupportedOperationException();} }Spy - Mock 1个真实 对象 有1个场景 1个类里定义了n个方法 我只想让定义某个方法的行为 但是要让其他方法正常执行 当然我们可以Mock 这个对象后 把其他的方法都打桩为CallRealMethod, 但是这个方法很蠢 更好的方法是Spy 1个对象 Mockito Spy 对象定义 什么是Spy 在Mockito中spy是一种特殊类型的mock对象它可以部分模拟一个真实对象。 与普通的mock对象不同spy对象保留了被模拟对象的真实行为除非显式进行了模拟。Spy对象的特点 Spy对象会保留被模拟对象的原始行为除非显式指定了模拟行为。 通过spy创建的对象是真实对象的一个代理可以使用Mockito的方法来验证其行为。 可以通过spy对象来监视真实对象的方法调用并可以选择性地进行模拟。Spy的使用场景 当您想要部分模拟一个真实对象同时保留其原始行为时可以使用spy对象。 适用于需要对对象的部分方法进行跟踪或验证的情况而不需要完全模拟整个对象。构建1个Spy 对象 方法一 我们可以用Mockito.spy() 来创建 例如: SpyUtil Mockito.spy(StringUtil.class)方法二 我们可以用Spy 来定义 同样需要ExtendWith(MockitoExtension.class) 例如 ExtendWith(MockitoExtension.class) class xxxSpy private StringUtil spyUtil;spy的打桩 其实spy的打桩与mock对象的打桩无任何区别 只不过mock对象的方法默认不打桩的话就是不执行任何代码 而spy 则相反 不打桩的话会执行真实代码 例子 下面的Spy对象有两个方法 其中1个方法循环调用另1个方法 而这里只Stub了第2个方法 让外部方法正常执行循环 ExtendWith(MockitoExtension.class) public class SpyTest {Spyprivate StringUtil8 spyUtil;Testvoid testRealMethod() {StringUtil8 util new StringUtil8();ListString list Arrays.asList(test, test2);util.formatString(list);//assert the listListString expected Arrays.asList(test: 20240101, test2: 20240101);assertEquals(expected,list);}Testvoid testSpyMethod() {ListString list Arrays.asList(test, test2);given(spyUtil.formatString(Mockito.any(String.class))).willAnswer((invocation) - invocation.getArgument(0) : 20241111);spyUtil.formatString(list);//assert the listListString expected Arrays.asList(test: 20241111, test2: 20241111);assertEquals(expected,list);}}Slf4j class StringUtil8 {public void formatString(ListString list) {list.replaceAll(this::formatString);log.info(list: {}, list);}public String formatString(String str) {return str : 20240101;} }Mock 1个静态方法 – MockStatic 上面的例子都是Mock 1个对象内的方法。 而且Mock内的对象对真实其他对象的相同方法是无影响的 它们分布在不同的heap 内存 问题来了 如果1个静态方法可以被mock吗 因为1个类的静态方法是共享的 即使这个类创建了多个对象。 Mocktio.core 早期并不支持Mock 静态方法 但是现在可以了 例子 ExtendWith(MockitoExtension.class) public class MockitoStaticTest {Testvoid testMockitoStatic() {try (MockedStaticStringUtil9 mockStaticObj Mockito.mockStatic(StringUtil9.class)) {given(StringUtil9.formatString(Mockito.any(String.class))).willReturn(test: 20241111);assertEquals(test: 20241111, StringUtil9.formatString(test));} // try will auto execute the mockStaticObj.close()assertEquals(test: 20000101, StringUtil9.formatString(test));} }class StringUtil9 {public static String formatString(String str) {return str : 20000101;} } 注意 强烈建议使用try with resource block 来使用 mockstatic 否则你需要手动close mockobj, otherwise 程序不知道mock 什么时候结束 Inject 1个Mock 对象到另1个真实对象 大部分我们要面对的场景是 我们要测试A类, A有1个B类成员 b B类的方法对环境有依赖 所以我们要mock 1个B对象 然后让B对象成为A测试对象的1个成员 方法有多种 方法一 通过构造函数inject Mock private B b;Test testA(){A a new A(b)//Stubgiven(b.....)assert(A....) }但是很多时候B 是通过反射注入的(Spring) A并没有1个有参的构造函数 方法二 同过反射注入Mock - ReflectionTestUtils Mock private B b;Test testA(){A a new A()ReflectionTestUtils.setField(a, b, b); // “b is the properties name in class A//Stubgiven(b.....)assert(A....) }方法三 同过InjectMocks 注解 Mock private B b;InjectMocks private A aTest testA(){//Stubgiven(b.....)assert(A....) }项目更多地用这种写法 注意 InjectMocks 还是基于反射注入Mock 对象会把所有用Mock orSpy 定义的mock 对象注入到InjectMocks的对象中InjectMock 默认会使用类A 的无参函数来构建A对象a, 如果A没有 无参函数有可能会有异常可以使用 InjectMocks(constructorArgs {“dependency1”, “dependency2”}) 来指定使用某个有参函数 例子 RunWith(MockitoJUnitRunner.class) public class MockitoInjectMocksTest {Mockprivate Dependency1 dependency1;Mockprivate Dependency2 dependency2;InjectMocks(constructorArgs {dependency1, dependency2})private MyClass myClass;Testpublic void testMyClass() {// ...}public static class MyClass {private final Dependency1 dependency1;private final Dependency2 dependency2;public MyClass(Dependency1 dependency1, Dependency2 dependency2) {this.dependency1 dependency1;this.dependency2 dependency2;}// ...}public interface Dependency1 {// ...}public interface Dependency2 {// ...} }用Mockito去解决本文开始提供的场景问题 很明显 上面的A类就是 场景下的Service 类 B类就是Dao 类 Dao类具有DB 的依赖 重写后的test 方法 Slf4j ExtendWith(MockitoExtension.class) class OrderServiceBddTest {Mockprivate OrderDao orderDao;InjectMocksprivate OrderService orderService;private Order orderToTest;private Order orderDetails;BeforeEachvoid beforeEach() {orderToTest Order.builder().commodityName(ASUS ROG ZEPHYRUS).price(3L).userId(3L).build();orderDetails Order.builder().commodityName(ASUS ROG ZEPHYRUS V3).price(4L).build();}Testvoid updateOrder() {log.info(updateOrder test start);// happy flow // force the orderDao to return the orderToTestgiven(orderDao.findById(Mockito.anyLong())).willReturn(Optional.of(orderToTest));// let orderDao.save() successfully return the orderToTestgiven(orderDao.save(any(Order.class))).willAnswer(invocation - invocation.getArgument(0));Order orderUpdated orderService.updateOrder(101L, orderDetails);Mockito.verify(orderDao).findById(101L);//Mockito.verify(orderService).queryById(101L); // not workassertEquals(orderDetails.getCommodityName(), orderUpdated.getCommodityName());assertEquals(orderDetails.getPrice(), orderUpdated.getPrice());// exception case 1 , order not found // clean all stubs for an objectMockito.reset(orderDao);given(orderDao.findById(Mockito.anyLong())).willThrow(NoSuchElementException.class);assertThrows(NoSuchElementException.class, () - orderService.updateOrder(101L, orderDetails));// exception case 1 , order not found Mockito.reset(orderDao);given(orderDao.findById(Mockito.anyLong())).willThrow(QueryTimeoutException.class);assertDoesNotThrow(() - orderService.updateOrder(101L, orderDetails));Mockito.verify(orderDao).findById(101L);assertNull(orderService.updateOrder(101L, orderDetails));} }可以见到 使用mockito 我们很容易模拟db timeout 和 没有数据的问题 真正地令覆盖率达到100% Mockito 的verify 我认为verify 也是断言(Assert)的一种 一种特殊的断言 只能用于mock 对象上 verify 可以用于检查mock 对象的方法执行次数 和执行时的参数等 个人并不常用 例子 参考上面的例子
http://www.w-s-a.com/news/995159/

相关文章:

  • 湖南做网站 在线磐石网络百度一下百度搜索
  • 现在建网站多少钱推广营销费
  • 联想企业网站建设的思路西安网站建设阳建
  • 网站内容 内链网站建设电话销售工作总结
  • 系统网站开发知名的摄影网站有哪些
  • 网站拍照的幕布扬中网站建设价位
  • 网站ie兼容性差西安小程序开发的公司
  • 上海网站建设培训app网站开发成本
  • 个人网站icp外贸网站开发 河南
  • 遵义建设网站无锡市规划建设局网站
  • 海外留学网站建设方案门户网站的发布特点
  • 网站建设不赚钱net112企业建站系统
  • 网站建设团队管理模板贵州省住房和城乡建设部网站
  • 曲沃网站建设网上学编程的有哪些比较好的网站
  • 厦门网站建设慕枫学做网站需要多久
  • 爱奇艺做任务领vip网站设计广告图片
  • 中科汇联网站建设手册上海公司名称注册查询网
  • 网站建设电子商务课总结和体会关于做网站书籍
  • 仪征网站建设公司哪家好简单网页制作素材图片
  • 甘肃第九建设集团公司网站潍坊个人做网站
  • 如何做后台网站的教程网站建设 关于我们
  • 极速网站建设哪家好连云港百度推广网站建设
  • 医院网站建设的目标wordpress中英文网站模板
  • 门户型网站开发难度网站导航栏有哪些
  • 推荐做任务网站软件定制开发哪家好
  • 邯郸兄弟建站第三方仓储配送公司
  • 商丘家具网站建设wordpress 添加代码
  • 基础建设的网站有哪些内容成都科技网站建设咨询电话
  • 券多多是谁做的网站招聘网站开发模板
  • 网站主机一般选哪种的企业数字展厅