<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>软件 on JackyLee&#39;s Blog</title>
    <link>https://jackylee3362.github.io/categories/%E8%BD%AF%E4%BB%B6/</link>
    <description>Recent content in 软件 on JackyLee&#39;s Blog</description>
    <image>
      <title>JackyLee&#39;s Blog</title>
      <url>https://jackylee3362.github.io/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</url>
      <link>https://jackylee3362.github.io/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</link>
    </image>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Thu, 30 Jul 2026 00:04:42 +0800</lastBuildDate>
    <atom:link href="https://jackylee3362.github.io/categories/%E8%BD%AF%E4%BB%B6/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Awesome 收集箱</title>
      <link>https://jackylee3362.github.io/article/software/awesome-collection/</link>
      <pubDate>Thu, 30 Jul 2026 00:04:42 +0800</pubDate>
      <guid>https://jackylee3362.github.io/article/software/awesome-collection/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;一份精心整理的命令行应用程序列表。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;收集箱&#34;&gt;收集箱&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/aldanial/cloc&#34;&gt;cloc&lt;/a&gt; - 统计代码行数&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/nvbn/thefuck&#34;&gt;thefuck&lt;/a&gt; - 修复上一条命令&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;awesome-类&#34;&gt;Awesome 类&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/agarrharr/awesome-cli-apps&#34;&gt;awesome-cli-apps&lt;/a&gt; 仓库&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/maguowei/awesome-stars&#34;&gt;awesome-stars&lt;/a&gt; - Awesome 系列 Star 数量&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;开发&#34;&gt;开发&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/captainsafia/legit&#34;&gt;legit&lt;/a&gt; - 将开源许可证生成为文件或文件头。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/cezaraugusto/mklicense&#34;&gt;mklicense&lt;/a&gt; - 轻松创建包含自定义信息的 LICENSE 文件。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/shobrook/rebound&#34;&gt;rebound&lt;/a&gt; - 在编译器报错时获取 Stack Overflow 结果。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/zaaack/foy&#34;&gt;foy&lt;/a&gt; - 轻量级通用任务运行器/构建工具。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/casey/just&#34;&gt;just&lt;/a&gt; - 现代化的类 &lt;code&gt;make&lt;/code&gt; 命令运行器。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jarun/bcal&#34;&gt;bcal&lt;/a&gt; - 用于存储转换和计算的字节计算器。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/mellowcandle/bitwise&#34;&gt;bitwise&lt;/a&gt; - 进制转换和位操作工具。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/bnagy/cgasm&#34;&gt;cgasm&lt;/a&gt; - x86 汇编文档。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/pemistahl/grex&#34;&gt;grex&lt;/a&gt; - 根据用户提供的测试用例生成正则表达式。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/pvarentsov/iola&#34;&gt;iola&lt;/a&gt; - 带 REST API 的 Socket 客户端。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/TejasQ/add-gitignore&#34;&gt;add-gitignore&lt;/a&gt; - 根据你的需求交互式地生成 .gitignore 文件。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/sindresorhus/is-up-cli&#34;&gt;is-up-cli&lt;/a&gt; - 检查域名是否在线。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/italolelis/reachable&#34;&gt;reachable&lt;/a&gt; - 检查域名是否可达。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/rtfpessoa/diff2html-cli&#34;&gt;diff2html-cli&lt;/a&gt; - 从 diff 创建美观的 HTML。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/pycontribs/mk&#34;&gt;mk&lt;/a&gt; - 暴露不熟悉的仓库中最常见的操作。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Chrilleweb/dotenv-diff&#34;&gt;dotenv-diff&lt;/a&gt; - 验证代码库中环境变量的使用情况。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ota-run/ota&#34;&gt;ota&lt;/a&gt; - 跨技术栈的统一可诊断仓库设置（本地、部署、CI、智能体）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;文本编辑器&#34;&gt;文本编辑器&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/emacs-mirror/emacs&#34;&gt;emacs&lt;/a&gt; - 一款可扩展、可定制、自由/免费的文本编辑器——远不止于此。&lt;/p&gt;</description>
    </item>
    <item>
      <title>开源博客框架横向对比</title>
      <link>https://jackylee3362.github.io/posts/2026/260728-02-blog-framework-compare/</link>
      <pubDate>Tue, 28 Jul 2026 18:41:49 +0800</pubDate>
      <guid>https://jackylee3362.github.io/posts/2026/260728-02-blog-framework-compare/</guid>
      <description>&lt;h2 id=&#34;博客对比&#34;&gt;博客对比&lt;/h2&gt;
&lt;h2 id=&#34;一静态站点框架&#34;&gt;一、静态站点框架&lt;/h2&gt;
&lt;h3 id=&#34;hugogo&#34;&gt;Hugo(Go)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;仓库：&lt;a href=&#34;https://github.com/gohugoio/hugo&#34;&gt;gohugoio/hugo&lt;/a&gt; 89K&lt;/li&gt;
&lt;li&gt;开发语言：Go&lt;/li&gt;
&lt;li&gt;是否需要构建：✅ 需要预构建&lt;/li&gt;
&lt;li&gt;主题生态：极其丰富，博客主题众多&lt;/li&gt;
&lt;li&gt;推荐主题：&lt;a href=&#34;https://github.com/adityatelange/hugo-PaperMod&#34;&gt;PaperMod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;模板语法：Go Template&lt;/li&gt;
&lt;li&gt;依赖要求：单二进制，&lt;strong&gt;零外部依赖&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;最大短板：Go模板语法晦涩难懂，自定义学习成本偏高&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;astrots&#34;&gt;Astro(TS)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;仓库：&lt;a href=&#34;https://github.com/withastro/astro&#34;&gt;withastro/astro&lt;/a&gt; 61K&lt;/li&gt;
&lt;li&gt;开发语言：TypeScript&lt;/li&gt;
&lt;li&gt;是否需要构建：✅ 需要预构建&lt;/li&gt;
&lt;li&gt;主题生态：中等，官网/文档居多，成熟博客主题偏少&lt;/li&gt;
&lt;li&gt;推荐主题：&lt;a href=&#34;https://github.com/satnaing/astro-paper&#34;&gt;AstroPaper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;模板语法：Astro组件语法，支持Vue/React/Svelte&lt;/li&gt;
&lt;li&gt;依赖要求：Node.js环境&lt;/li&gt;
&lt;li&gt;最大短板：博客基础能力（标签系统、分页）需要手动搭建&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;hexots&#34;&gt;Hexo(TS)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;仓库：&lt;a href=&#34;https://github.com/hexojs/hexo&#34;&gt;hexojs/hexo&lt;/a&gt; 41K&lt;/li&gt;
&lt;li&gt;开发语言：TypeScript&lt;/li&gt;
&lt;li&gt;是否需要构建：✅ 需要预构建&lt;/li&gt;
&lt;li&gt;主题生态：中文生态成熟，海量博客主题&lt;/li&gt;
&lt;li&gt;推荐主题：&lt;a href=&#34;https://github.com/jerryc127/hexo-theme-butterfly&#34;&gt;Butterfly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;模板语法：JavaScript&lt;/li&gt;
&lt;li&gt;依赖要求：Node.js&lt;/li&gt;
&lt;li&gt;最大短板：文章数量庞大后构建速度下降；Node依赖容易出现版本冲突&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;docsifyjs&#34;&gt;Docsify(JS)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;仓库：&lt;a href=&#34;https://github.com/docsifyjs/docsify&#34;&gt;docsifyjs/docsify&lt;/a&gt; 31K&lt;/li&gt;
&lt;li&gt;开发语言：JavaScript&lt;/li&gt;
&lt;li&gt;是否需要构建：❌ 无需构建&lt;/li&gt;
&lt;li&gt;主题生态：轻量文档主题为主，博客生态薄弱&lt;/li&gt;
&lt;li&gt;推荐主题：&lt;a href=&#34;https://github.com/docsifyjs/themeable&#34;&gt;docsify-themeable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;模板语法：HTML/JS&lt;/li&gt;
&lt;li&gt;依赖要求：仅静态文件托管，无构建依赖&lt;/li&gt;
&lt;li&gt;最大短板：客户端实时渲染，SEO差；源码直接暴露，不适合公开博客&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;zolarust&#34;&gt;Zola(Rust)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;仓库：&lt;a href=&#34;https://github.com/getzola/zola&#34;&gt;getzola/zola&lt;/a&gt; 18K&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;开发语言：Rust&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;是否需要构建：✅ 需要预构建&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;主题生态：中等，数量远少于Hugo，文档向居多&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;推荐主题：&lt;a href=&#34;https://github.com/geph/zola-deep-thought&#34;&gt;DeepThought&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;模板语法：Tera（类Jinja2）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;依赖要求：单二进制，零外部依赖&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;最大短板：社区体量小，插件、现成博客主题较少&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://yfaming.com/post/blog-with-zola/&#34;&gt;如何用 zola 搭建个人博客&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;vitepressts&#34;&gt;VitePress(TS)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;仓库：&lt;a href=&#34;https://github.com/vuejs/vitepress&#34;&gt;vuejs/vitepress&lt;/a&gt; 18K&lt;/li&gt;
&lt;li&gt;开发语言：TypeScript(Vue)&lt;/li&gt;
&lt;li&gt;是否需要构建：✅ 需要预构建&lt;/li&gt;
&lt;li&gt;主题生态：偏向文档主题，博客方案需自行封装&lt;/li&gt;
&lt;li&gt;推荐主题：&lt;a href=&#34;https://github.com/vitepress/vitepress&#34;&gt;vitepress-theme-demoblock&lt;/a&gt;（官方默认扩展）&lt;/li&gt;
&lt;li&gt;模板语法：Vue模板 + Markdown&lt;/li&gt;
&lt;li&gt;依赖要求：Node.js环境，依赖较多&lt;/li&gt;
&lt;li&gt;最大短板：原生不以博客为目标，标签、分页、封面需要二次开发&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;eleventyjs&#34;&gt;Eleventy(JS)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;仓库：&lt;a href=&#34;https://github.com/11ty/eleventy&#34;&gt;11ty/eleventy&lt;/a&gt; 19.8K&lt;/li&gt;
&lt;li&gt;开发语言：JavaScript&lt;/li&gt;
&lt;li&gt;是否需要构建：✅ 需要预构建&lt;/li&gt;
&lt;li&gt;主题生态：极少开箱即用博客主题&lt;/li&gt;
&lt;li&gt;推荐主题：&lt;a href=&#34;https://github.com/11ty/eleventy-base-blog&#34;&gt;eleventy-base-blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;模板语法：自由选择：Nunjucks/Handlebars等&lt;/li&gt;
&lt;li&gt;依赖要求：Node.js&lt;/li&gt;
&lt;li&gt;最大短板：高度自由但几乎没有完整成品模板，适合愿意手写页面的开发者&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;nextrats&#34;&gt;Nextra(TS)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;仓库：&lt;a href=&#34;https://github.com/shuding/nextra&#34;&gt;shuding/nextra&lt;/a&gt; 13.9K&lt;/li&gt;
&lt;li&gt;开发语言：TypeScript&lt;/li&gt;
&lt;li&gt;是否需要构建：✅ 需要预构建&lt;/li&gt;
&lt;li&gt;主题生态：文档向为主，适合技术站点&lt;/li&gt;
&lt;li&gt;推荐主题：nextra 默认主题&lt;/li&gt;
&lt;li&gt;模板语法：React/MDX&lt;/li&gt;
&lt;li&gt;依赖要求：Node.js、Next.js较重依赖&lt;/li&gt;
&lt;li&gt;最大短板：资源占用高；偏向文档，纯个人博客属于重度方案&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;二动态博客程序php数据库驱动&#34;&gt;二、动态博客程序（PHP，数据库驱动）&lt;/h2&gt;
&lt;h3 id=&#34;wordpressphp&#34;&gt;WordPress(PHP)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;仓库：&lt;a href=&#34;https://github.com/WordPress/WordPress&#34;&gt;WordPress&lt;/a&gt; 18.6K&lt;/li&gt;
&lt;li&gt;开发语言：PHP&lt;/li&gt;
&lt;li&gt;是否需要构建：❌ 动态程序，无需预构建&lt;/li&gt;
&lt;li&gt;主题生态：全球海量付费+免费博客主题&lt;/li&gt;
&lt;li&gt;推荐主题：&lt;a href=&#34;https://wpastra.com/&#34;&gt;Astra&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;依赖要求：PHP + MySQL/MariaDB&lt;/li&gt;
&lt;li&gt;最大短板：插件繁多容易臃肿、安全漏洞多、访问速度一般&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;typechophp&#34;&gt;Typecho(PHP)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;仓库：&lt;a href=&#34;https://github.com/typecho/typecho&#34;&gt;typecho/typecho&lt;/a&gt; 12.4K&lt;/li&gt;
&lt;li&gt;开发语言：PHP&lt;/li&gt;
&lt;li&gt;是否需要构建：❌ 动态程序，无需预构建&lt;/li&gt;
&lt;li&gt;主题生态：国内轻量化博客主题丰富&lt;/li&gt;
&lt;li&gt;推荐主题：&lt;a href=&#34;https://github.com/AlanDecode/Mirages&#34;&gt;Mirages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;依赖要求：PHP + SQLite / MySQL&lt;/li&gt;
&lt;li&gt;最大短板：更新缓慢，社区活跃度逐年降低，插件数量有限&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>如何优雅地使用 spock 框架写单测</title>
      <link>https://jackylee3362.github.io/posts/2024/240726-01-how-to-wirte-spock/</link>
      <pubDate>Fri, 26 Jul 2024 22:01:31 +0800</pubDate>
      <guid>https://jackylee3362.github.io/posts/2024/240726-01-how-to-wirte-spock/</guid>
      <description>&lt;h2 id=&#34;添加-spock-依赖&#34;&gt;添加 Spock 依赖&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;&amp;lt;!-- 1.Spock 相关 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.spockframework&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spock-core&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.3-groovy-2.4&lt;span class=&#34;nt&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class=&#34;nt&#34;&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.spockframework&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spock-spring&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.3-groovy-2.4&lt;span class=&#34;nt&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class=&#34;nt&#34;&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;&amp;lt;!-- 2.PowerMock 相关--&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.powermock&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;powermock-module-junit4&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0.4&lt;span class=&#34;nt&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class=&#34;nt&#34;&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.powermock&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;powermock-api-mockito2&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0.4&lt;span class=&#34;nt&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class=&#34;nt&#34;&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;单测-demo&#34;&gt;单测 Demo&lt;/h2&gt;
&lt;h3 id=&#34;静态类单测-demo&#34;&gt;静态类单测 Demo&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@RunWith&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PowerMockRunner&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@PowerMockRunnerDelegate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sputnik&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 交给 spock 代理执行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@PrepareForTest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;静态类&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@SuppressStaticInitializationFor&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;静态类全名&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 限制静态类里的静态代码块初始化
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;StaticMethodSpec&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;extends&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Specification&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;service&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Mock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UserService&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;controller&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UserController&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;userService:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;service&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// Mock静态类
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;PowerMockito&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;mockStatic&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;静态类&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nd&#34;&gt;@Unroll&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;测试类名 #desc&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nl&#34;&gt;given:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;给定条件&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;service&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getById&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Integer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;name:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Alice&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nl&#34;&gt;age:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;k1:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nl&#34;&gt;k2:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;list&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nl&#34;&gt;and:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;mock静态方法返回值&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;PowerMockito&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;when&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;静态类&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;静态方法&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mockito&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;any&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;())).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;thenReturn&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;自己想要的返回值&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nl&#34;&gt;when:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;调用时&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;res&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;controller&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getById&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v_id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nl&#34;&gt;then:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;比较&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;res&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// 或者
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;res&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;v_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;age&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;v_age&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;where&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;数据格式&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt;      &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;v_id&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;success&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;name:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Alice&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nl&#34;&gt;age:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;fail&amp;#34;&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;捕获异常&#34;&gt;捕获异常&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;test 测试类&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;//...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nl&#34;&gt;then:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exception&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;thrown&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v_expectException&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;exception&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;v_expectCode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;exception&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;v_expectMessage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;校验参数&#34;&gt;校验参数&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;test 测试类&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;//...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nl&#34;&gt;then:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;某类&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;某方法&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;某属性&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;属性&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;某属性&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;属性&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;参考文献&#34;&gt;参考文献&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://tech.meituan.com/2021/08/06/spock-practice-in-meituan.html&#34;&gt;Spock 单元测试框架介绍以及在美团优选的实践&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>随想，看看 Joyful Pandas 项目</title>
      <link>https://jackylee3362.github.io/posts/2024/240406-01-joyful-pandas/</link>
      <pubDate>Sat, 06 Apr 2024 00:52:55 +0800</pubDate>
      <guid>https://jackylee3362.github.io/posts/2024/240406-01-joyful-pandas/</guid>
      <description>&lt;p&gt;最近准备复现一些实验，每次都要重新学 Pandas 的一些语法，刚好看到了这个仓库&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/datawhalechina/joyful-pandas&#34;&gt;joyful-pandas&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;仓库介绍&#34;&gt;仓库介绍&lt;/h2&gt;
&lt;p&gt;作者是 &lt;a href=&#34;https://github.com/datawhalechina&#34;&gt;Datawhale&lt;/a&gt;，一个专注于数据科学与 AI 领域的开源组织(有 100+ 个仓库，超级厉害！)&lt;/p&gt;
&lt;p&gt;2020.1.20 建立仓库，初始化 README.md&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gh&#34;&gt;# Joyful-Pandas
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;A Complete Guide for Pandas Learners
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;5 年期间不断更新，最近一次是在 2024.10.17，更新了英文的介绍&lt;/p&gt;
&lt;h2 id=&#34;代码方面&#34;&gt;代码方面&lt;/h2&gt;
&lt;p&gt;代码写的非常优雅，
不过因为我的 Pandas 版本比较高，
导致部分函数失效，
比如 &lt;code&gt;DataFrame&lt;/code&gt; 的 &lt;code&gt;mad&lt;/code&gt; 函数，
在 &lt;code&gt;pandas&lt;/code&gt; 的 &lt;code&gt;2.0&lt;/code&gt; 版本之后就废弃了&lt;/p&gt;
&lt;p&gt;或者说使用 &lt;code&gt;any(1)&lt;/code&gt; 或者 &lt;code&gt;all(1)&lt;/code&gt; 时，
新版的 Pandas 需要显示地指定形参名，
所以建议改为 &lt;code&gt;any(axis=1)&lt;/code&gt; 和 &lt;code&gt;all(axis=1)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;然后就是格式化稍微有点问题（不影响代码运行）&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我的评价是是个非常好的教程仓库！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;参考&#34;&gt;参考&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/datawhalechina/joyful-pandas&#34;&gt;datawhalechina/joyful-pandas: pandas 中文教程&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Git 一些比较复杂的使用场景</title>
      <link>https://jackylee3362.github.io/posts/2024/240406-02-git-situation/</link>
      <pubDate>Wed, 03 Apr 2024 13:53:54 +0800</pubDate>
      <guid>https://jackylee3362.github.io/posts/2024/240406-02-git-situation/</guid>
      <description>&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;平常使用 &lt;code&gt;git add .&lt;/code&gt; 或者 &lt;code&gt;git push|pull|clone&lt;/code&gt; 等命令，已经无法满足各种奇怪的需求了，&lt;/p&gt;
&lt;p&gt;在使用 Github 的时候，由于对【本地分支】和【远程分支】理解不够深刻，难免会出现各种问题&lt;/p&gt;
&lt;p&gt;所以本文章持续记录使用 Git 时遇到的各种复杂场景&lt;/p&gt;
&lt;h2 id=&#34;1-本地分支相关&#34;&gt;1 本地分支相关&lt;/h2&gt;
&lt;h3 id=&#34;11-签出会覆盖本地修改&#34;&gt;1.1 签出会覆盖本地修改&lt;/h3&gt;
&lt;p&gt;场景描述：&lt;/p&gt;
&lt;p&gt;通常我会在 &lt;code&gt;dev&lt;/code&gt; 分支上操作，
然后细粒度地提交 commit，
上传到 github 上形成一个 pull-request，
然后 &lt;code&gt;main&lt;/code&gt; 再接受 pr，然后合并成一个&lt;/p&gt;
&lt;p&gt;但是有时候会忘记切换分支（比如现在就是），直接在 main 上更改&lt;/p&gt;
&lt;p&gt;在 vscode 的状态栏就会出现 &lt;code&gt;*&lt;/code&gt;，此时想换到 &lt;code&gt;dev&lt;/code&gt; 分支&lt;/p&gt;
&lt;p&gt;直接切换会出现&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;签出会覆盖本地修改&#34; loading=&#34;lazy&#34; src=&#34;https://assets-1302294329.cos.ap-shanghai.myqcloud.com/2026/md/override-local-change.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;该提示下的三个选项分别是什么意思呢？&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;储藏并签出：希望【暂存区】仍然在当前分支，然后切换到另一个分支&lt;/li&gt;
&lt;li&gt;迁移更改：希望将【暂存区】的内容切换到另一个分支，可能要处理冲突问题&lt;/li&gt;
&lt;li&gt;强制签出：（不推荐）直接放弃当前分支（比如 &lt;code&gt;main&lt;/code&gt;）未提交的 &lt;code&gt;commmit&lt;/code&gt;，然后切换为分支 &lt;code&gt;dev&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以该场景我们需要的是【迁移更改】&lt;/p&gt;
&lt;h3 id=&#34;12-暂存-apply-和-pop&#34;&gt;1.2 暂存 apply 和 pop&lt;/h3&gt;
&lt;p&gt;什么时候需要【储藏并签出】呢？&lt;/p&gt;
&lt;p&gt;比如当自己在 &lt;code&gt;a-branch&lt;/code&gt; 上写代码，突然有紧急的 bug 需要在 &lt;code&gt;b-branch&lt;/code&gt; 维修，但是 &lt;code&gt;a-branch&lt;/code&gt; 还没到达可以提交的阶段，此时就可以使用【储藏并签出】的功能&lt;/p&gt;
&lt;p&gt;在修改完以后，回到原先的分支，可以看到 stash 的小图标&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hugo 简易教程</title>
      <link>https://jackylee3362.github.io/posts/2024/240403-02-hugo-tutorial/</link>
      <pubDate>Wed, 03 Apr 2024 11:00:30 +0800</pubDate>
      <guid>https://jackylee3362.github.io/posts/2024/240403-02-hugo-tutorial/</guid>
      <description>&lt;h2 id=&#34;介绍&#34;&gt;介绍&lt;/h2&gt;
&lt;p&gt;Hugo 是一个由 Go 语言编写的静态博客框架&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;仓库地址: &lt;a href=&#34;https://github.com/gohugoio/hugo&#34;&gt;Hugo - github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;安装&#34;&gt;安装&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# windows&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;scoop install hugo
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# unix&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install hugo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;配置文件&#34;&gt;配置文件&lt;/h2&gt;
&lt;p&gt;默认的配置文件&lt;/p&gt;
&lt;h2 id=&#34;主题&#34;&gt;主题&lt;/h2&gt;
&lt;p&gt;默认使用 PapaeMod 这个主题&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/adityatelange/hugo-PaperMod/wiki/Installation#sample-configyml&#34;&gt;sample-config.yml | hugo-PaperMod Wiki&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;更新工作流&#34;&gt;更新工作流&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;第一步: 生成文章模板&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 默认模板&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;hugo new post/xxx.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 指定模板&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;hugo new --kind &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;archetypes&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; post/xxx.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;## 例如&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;hugo new --kind post post/whatever.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;第二步: 内容创作&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第三步: 提交与发布&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果是草稿态，记得打开 &lt;code&gt;draft:true&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;faq&#34;&gt;FAQ&lt;/h2&gt;
&lt;h3 id=&#34;q1-如果添加图片&#34;&gt;Q1: 如果添加图片&lt;/h3&gt;
&lt;p&gt;第一种方案: 用图床&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;崩坏星穹铁道&#34; loading=&#34;lazy&#34; src=&#34;https://assets-1302294329.cos.ap-shanghai.myqcloud.com/2026/md/20260728162921.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;第二种方案: 使用 index.md 方法，可以参考下文&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.yuweihung.com/posts/2021/hugo-blog-picture/&#34;&gt;Hugo 博客插入图片的方法 | Cassius&amp;rsquo;s Blog&lt;/a&gt;&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
