PageSourceSearch

https://ncat-bot-docs-delta.vercel.app/assets/index.html-BxJ5Qp7b.js

js ncat-bot-docs-delta.vercel.app collected 2026-10-03 07:23:20 UTC 30,874 bytes, 45 lines download raw bytes

1import{_ as l,c as h,a as k,b as a,e as i,d as n,w as e,r as p,o as d}from"./app-C1L7GXRS.js";const r={};function o(c,s){const t=p("RouteLink");return d(),h("div",null,[s[6]||(s[6]=k(`<blockquote><p>Mock 适配器使用指南 — 用于插件集成测试的内存适配器,无需网络连接。</p></blockquote><hr><h2 id="quick-reference" tabindex="-1"><a class="header-anchor" href="#quick-reference"><span>Quick Reference</span></a></h2><table><thead><tr><th>属性</th><th>值</th></tr></thead><tbody><tr><td>适配器名称</td><td><code>mock</code></td></tr><tr><td>平台标识</td><td><code>mock</code>(可自定义)</td></tr><tr><td>协议</td><td>内存模拟</td></tr><tr><td>类</td><td><code>MockAdapter</code></td></tr><tr><td>导入</td><td><code>from ncatbot.adapter import MockAdapter</code></td></tr></tbody></table><hr><h2 id="概述" tabindex="-1"><a class="header-anchor" href="#概述"><span>概述</span></a></h2><p>Mock 适配器不连接任何外部服务,完全在内存中运行。它的主要用途是:</p><ul><li><strong>插件集成测试</strong>:注入模拟事件,验证插件行为</li><li><strong>API 调用验证</strong>:记录所有 API 调用,断言调用参数和次数</li><li><strong>无网络开发</strong>:不需要运行 NapCat 或其他外部服务</li></ul><hr><h2 id="基本用法" tabindex="-1"><a class="header-anchor" href="#基本用法"><span>基本用法</span></a></h2><div class="language-python line-numbers-mode" data-ext="python" data-title="python"><button class="copy" title="复制代码" data-copied="已复制"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">from</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> ncatbot</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">app </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> BotClient</span></span>
2<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">from</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> ncatbot</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">adapter </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> MockAdapter</span></span>
3<span class="line"></span>
4<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">adapter </span><span style="--shiki-light:#999999;--shiki-dark:#666666;">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> MockAdapter</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A;">platform</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">=</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">qq</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">)</span></span>
5<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">bot </span><span style="--shiki-light:#999999;--shiki-dark:#666666;">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> BotClient</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A;">adapters</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">=[</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">adapter</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">])</span></span>
6<span class="line"></span>
7<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># 启动后注入事件</span></span>
8<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">await</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> adapter</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">inject_event</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">some_event_data</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">)</span></span>
9<span class="line"></span>
10<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># 检查 API 调用</span></span>
11<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">assert</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> adapter</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">mock_api</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">called</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">
11send_group_msg</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">)</span></span>
12<span class="line"></span>
13<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># 停止</span></span>
14<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">adapter</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">stop</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">()</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="自定义平台标识" tabindex="-1"><a class="header-anchor" href="#自定义平台标识"><span>自定义平台标识</span></a></h3><p>Mock 适配器的 <code>platform</code> 可以自定义,模拟不同平台的事件。MockAdapter 会根据平台自动选择对应的 Mock API 实现:</p><div class="language-python line-numbers-mode" data-ext="python" data-title="python"><button class="copy" title="复制代码" data-copied="已复制"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">adapter </span><span style="--shiki-light:#999999;--shiki-dark:#666666;">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> MockAdapter</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A;">platform</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">=</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">qq</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">)</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;">        # → MockBotAPI (IQQAPIClient)</span></span>
15<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">adapter </span><span style="--shiki-light:#999999;--shiki-dark:#666666;">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> MockAdapter</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A;">platform</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">=</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">bilibili</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">)</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;">  # → MockBiliAPI (IBiliAPIClient)</span></span>
16<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">adapter </span><span style="--shiki-light:#999999;--shiki-dark:#666666;">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> MockAdapter</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A;">platform</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">=</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">github</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">)</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;">    # → MockGitHubAPI (IGitHubAPIClient)</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><hr><h2 id="mockapibase-继承体系" tabindex="-1"><a class="header-anchor" href="#mockapibase-继承体系"><span>MockAPIBase 继承体系</span></a></h2><p>所有 Mock API 共享基类 <code>MockAPIBase</code>
16,提供统一的调用录制和查询基础设施:</p><div class="language-text line-numbers-mode" data-ext="text" data-title="text"><button class="copy" title="复制代码" data-copied="已复制"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span>MockAPIBase (IAPIClient)</span></span>
17<span class="line"><span>├── MockBotAPI    (IQQAPIClient)     — QQ 平台</span></span>
18<span class="line"><span>├── MockBiliAPI   (IBiliAPIClient)   — Bilibili 平台</span></span>
19<span class="line"><span>└── MockGitHubAPI (IGitHubAPIClient) — GitHub 平台</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>每个子类的 API 方法以 <code>self._record(&quot;action&quot;, key=val, ...)</code> 形式录制调用,所有参数以关键字形式存储到 <code>APICall.params: Dict[str, Any]</code>。</p><h3 id="调用记录方法-mockapibase-提供" tabindex="-1"><a class="header-anchor" href="#调用记录方法-mockapibase-提供"><span>调用记录方法(MockAPIBase 提供)</span></a></h3><table><thead><tr><th>方法</th><th>签名</th><th>说明</th></tr></thead><tbody><tr><td><code>called</code></td><td><code>(action) → bool</code></td><td>检查 action 是否被调用过</td></tr><tr><td><code>call_count</code></td><td><code>(action) → int</code></td><td>获取调用次数</td></tr><tr><td><code>get_calls</code></td><td><code>(action) → List[APICall]</code></td><td>获取指定 action 的所有调用记录</td></tr><tr><td><code>last_call</code></td><td><code>(action=None) → Optional[APICall]</code></td><td>获取最后一次调用</td></tr><tr><td><code>calls</code></td><td><code>@property → List[APICall]</code></td><td>所有调用记录</td></tr><tr><td><code>set_response</code></td><td><code>(action, response) → None</code></td><td>为指定 action 预设返回值</td></tr><tr><td><code>reset</code></td><td><code>() → None</code></td><td>清除所有记录和预设</td></tr></tbody></table><h3 id="apicall-数据类" tabindex="-1"><a class="header-anchor" href="#apicall-数据类"><span>APICall 数据类</span></a></h3><div class="language-python line-numbers-mode" data-ext="python" data-title="python"><button class="copy" title="复制代码" data-copied="已复制"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">from</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> ncatbot</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">adapter</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">mock</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">api_base </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> APICall</span></span>
20<span class="line"></span>
21<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;">@</span><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">dataclass</span></span>
22<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;">class</span><span style="--shiki-light:#2E8F82;--shiki-dark:#5DA994;"> APICall</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span></span>
23<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">    action</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;"> str</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;">                # API 方法名</span></span>
24<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">    params</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> Dict</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">[</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">str</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> Any</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">]</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;">     # 所有参数按名存储</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="示例" tabindex="-1"><a class="header-anchor" href="#示例"><span>示例</span></a></h3><div class="language-python line-numbers-mode" data-ext="python" data-title="python"><button class="copy" title="复制代码" data-copied="已复制"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># 预设 API 返回值</span></span>
25<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">adapter</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">mock_api</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">set_response</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">
25send_group_msg</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> {</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">message_id</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91;"> 12345</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">})</span></span>
26<span class="line"></span>
27<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># 触发插件逻辑(注入事件)</span></span>
28<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">await</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> adapter</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">inject_event</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">event_data</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">)</span></span>
29<span class="line"></span>
30<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># 验证 API 被调用</span></span>
31<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">assert</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> adapter</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">mock_api</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">called</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">send_group_msg</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">)</span></span>
32<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">assert</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> adapter</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">mock_api</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">call_count</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">send_group_msg</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">)</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;"> ==</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91;"> 1</span></span>
33<span class="line"></span>
34<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># 检查调用参数</span></span>
35<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">call </span><span style="--shiki-light:#999999;--shiki-dark:#666666;">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> adapter</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">mock_api</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">last_call</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">
35send_group_msg</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">)</span></span>
36<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">assert</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> call</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">params</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">[</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">group_id</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">]</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676;"> ==</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> &quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">123456</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><hr><h2 id="与-testharness-的关系" tabindex="-1"><a class="header-anchor" href="#与-testharness-的关系"><span>与 TestHarness 的关系</span></a></h2><p><code>TestHarness</code> 和 <code>PluginTestHarness</code> 内部使用 <code>MockAdapter</code>。如果你使用测试框架,通常不需要直接操作 <code>MockAdapter</code>:</p><div class="language-python line-numbers-mode" data-ext="python" data-title="python"><button class="copy" title="复制代码" data-copied="已复制"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">from</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> ncatbot</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">testing </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> PluginTestHarness</span></span>
37<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">from</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> ncatbot</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">testing</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">factories</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">qq </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> group_message</span></span>
38<span class="line"></span>
39<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">async</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;"> with</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> PluginTestHarness</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span></span>
40<span class="line"><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A;">    plugin_names</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">=[</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">hello_world</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">],</span></span>
41<span class="line"><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A;">    plugins_dir</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">Path</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">plugins/</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">),</span></span>
42<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;">)</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;"> as</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> h</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span></span>
43<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">    await</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> h</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">inject</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">group_message</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">hello</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">))</span></span>
44<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">    await</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> h</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">settle</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">()</span></span>
45<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">    h</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">assert_api</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">(</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">
45send_group_msg</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">&quot;</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">).</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">called</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">()</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>直接使用 <code>MockAdapter</code> 适合需要更底层控制的测试场景。</p><hr><h2 id="延伸阅读" tabindex="-1"><a class="header-anchor" href="#延伸阅读"><span>延伸阅读</span></a></h2>`,32)),a("ul",null,[a("li",null,[s[1]||(s[1]=i("插件测试指南 → ")),n(t,{to:"/notes/guide/9.%20%E6%B5%8B%E8%AF%95%E6%8C%87%E5%8D%97/"},{default:e(()=>s[0]||(s[0]=[i("测试指南")])),_:1})]),a("li",null,[s[3]||(s[3]=i("适配器接口参考(含 MockAdapter API)→ ")),n(t,{to:"/notes/reference/7.%20%E9%80%82%E9%85%8D%E5%99%A8/"},{default:e(()=>s[2]||(s[2]=[i("适配器参考")])),_:1})]),a("li",null,[s[5]||(s[5]=i("TestHarness 详解 → ")),n(t,{to:"/notes/guide/9.%20%E6%B5%8B%E8%AF%95%E6%8C%87%E5%8D%97/2.%20%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7.html"},{default:e(()=>s[4]||(s[4]=[i("测试工具")])),_:1})])])])}const y=l(r,[["render",o],["__file","index.html.vue"]]),A=JSON.parse('{"path":"/guide/obgl9txz/","title":"Mock 适配器","lang":"zh-CN","frontmatter":{"title":"Mock 适配器","createTime":"2026/03/19 17:26:45","permalink":"/guide/obgl9txz/","description":"Mock 适配器使用指南 — 用于插件集成测试的内存适配器,无需网络连接。 Quick Reference 概述 Mock 适配器不连接任何外部服务,完全在内存中运行。它的主要用途是: 插件集成测试:注入模拟事件,验证插件行为 API 调用验证:记录所有 API 调用,断言调用参数和次数 无网络开发:不需要运行 NapCat 或其他外部服务 基本用法 ...","head":[["meta",{"property":"og:url","content":"http://docs.ncatbot.xyz/guide/obgl9txz/"}],["meta",{"property":"og:site_name","content":"NcatBot 文档"}],["meta",{"property":"og:title","content":"Mock 适配器"}],["meta",{"property":"og:description","content":"Mock 适配器使用指南 — 用于插件集成测试的内存适配器,无需网络连接。 Quick Reference 概述 Mock 适配器不连接任何外部服务,完全在内存中运行。它的主要用途是: 插件集成测试:注入模拟事件,验证插件行为 API 调用验证:记录所有 API 调用,断言调用参数和次数 无网络开发:不需要运行 NapCat 或其他外部服务 基本用法 ..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2026-04-30T14:41:02.000Z"}],["meta",{"property":"article:modified_time","content":"2026-04-30T14:41:02.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Mock 适配器\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2026-04-30T14:41:02.000Z\\",\\"author\\":[]}"]]},"headers":[],"readingTime":{"minutes":2.23,"words":669},"git":{"updatedTime":1777560062000,"contributors":[{"name":"GEYUANwuqi","username":"GEYUANwuqi","email":"[email protected]","commits":1,"avatar":"https://gravatar.com/avatar/1cf26d82e91dff657f3fa4d4911cdabcf7b76396339e886e69f99b15d4c8c808?d=retro"}]},"autoDesc":true,"filePathRelative":"notes/guide/2. 适配器/4. Mock 适配器.md"}');export{y as comp,A as data};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.