1"use strict";(self.webpackChunknonebot=self.webpackChunknonebot||[]).push([["3230"],{9636(e,n,s){s.r(n),s.d(n,{metadata:()=>t,default:()=>u,frontMatter:()=>l,contentTitle:()=>c,toc:()=>h,assets:()=>d});var t=JSON.parse('{"id":"best-practice/testing/behavior","title":"\u6D4B\u8BD5\u4E8B\u4EF6\u54CD\u5E94\u4E0E\u4F1A\u8BDD\u64CD\u4F5C","description":"\u6D4B\u8BD5\u4E8B\u4EF6\u54CD\u5E94\u3001\u5E73\u53F0\u63A5\u53E3\u8C03\u7528\u548C\u4F1A\u8BDD\u63A7\u5236","source":"@site/versioned_docs/version-2.5.0/best-practice/testing/behavior.mdx","sourceDirName":"best-practice/testing","slug":"/best-practice/testing/behavior","permalink":"/docs/best-practice/testing/behavior","draft":false,"unlisted":false,"editUrl":"https://github.com/nonebot/nonebot2/edit/master/website/versioned_docs/version-2.5.0/best-practice/testing/behavior.mdx","tags":[],"version":"2.5.0","lastUpdatedBy":"StarHeart","lastUpdatedAt":1785574664000,"sidebarPosition":2,"frontMatter":{"sidebar_position":2,"description":"\u6D4B\u8BD5\u4E8B\u4EF6\u54CD\u5E94\u3001\u5E73\u53F0\u63A5\u53E3\u8C03\u7528\u548C\u4F1A\u8BDD\u63A7\u5236"},"sidebar":"tutorial","previous":{"title":"\u914D\u7F6E\u4E0E\u6D4B\u8BD5\u4E8B\u4EF6\u54CD\u5E94\u5668","permalink":"/docs/best-practice/testing/"},"next":{"title":"\u6A21\u62DF\u7F51\u7EDC\u901A\u4FE1","permalink":"/docs/best-practice/testing/mock-network"}}'),r=s(62540),o=s(43023),a=s(36031),i=s(84993);let l={sidebar_position:2,description:"\u6D4B\u8BD5\u4E8B\u4EF6\u54CD\u5E94\u3001\u5E73\u53F0\u63A5\u53E3\u8C03\u7528\u548C\u4F1A\u8BDD\u63A7\u5236"},c="\u6D4B\u8BD5\u4E8B\u4EF6\u54CD\u5E94\u4E0E\u4F1A\u8BDD\u64CD\u4F5C",d={},h=[{value:"\u6D4B\u8BD5\u4E8B\u4EF6\u54CD\u5E94",id:"\u6D4B\u8BD5\u4E8B\u4EF6\u54CD\u5E94",level:2},{value:"\u6D4B\u8BD5\u5E73\u53F0\u63A5\u53E3\u4F7F\u7528",id:"\u6D4B\u8BD5\u5E73\u53F0\u63A5\u53E3\u4F7F\u7528",level:2},{value:"\u6D4B\u8BD5\u4F1A\u8BDD\u63A7\u5236",id:"\u6D4B\u8BD5\u4F1A\u8BDD\u63A7\u5236",level:2}];function p(e){let n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"\u6D4B\u8BD5\u4E8B\u4EF6\u54CD\u5E94\u4E0E\u4F1A\u8BDD\u64CD\u4F5C",children:"\u6D4B\u8BD5\u4E8B\u4EF6\u54CD\u5E94\u4E0E\u4F1A\u8BDD\u64CD\u4F5C"})}),"\n","\n",(0,r.jsxs)(n.p,{children:["\u5728 NoneBot \u63A5\u6536\u5230\u4E8B\u4EF6\u65F6\uFF0C\u4E8B\u4EF6\u54CD\u5E94\u5668\u6839\u636E\u4F18\u5148\u7EA7\u4F9D\u6B21\u901A\u8FC7\u6743\u9650\u3001\u54CD\u5E94\u89C4\u5219\u6765\u5224\u65AD\u5F53\u524D\u4E8B\u4EF6\u662F\u5426\u5E94\u8BE5\u89E6\u53D1\u3002\u4E8B\u4EF6\u54CD\u5E94\u6D41\u7A0B\u4E2D\uFF0C\u673A\u5668\u4EBA\u53EF\u80FD\u4F1A\u901A\u8FC7 ",(0,r.jsx)(n.code,{children:"send"})," \u53D1\u9001\u6D88\u606F\u6216\u8005\u8C03\u7528\u5E73\u53F0\u63A5\u53E3\u6765\u6267\u884C\u9884\u671F\u7684\u64CD\u4F5C\u3002\u56E0\u6B64\uFF0C\u6211\u4EEC\u9700\u8981\u5BF9\u8FD9\u4E24\u79CD\u64CD\u4F5C\u8FDB\u884C\u5355\u5143\u6D4B\u8BD5\u3002"]}),"\n",(0,r.jsx)(n.p,{children:"\u5728\u4E0A\u4E00\u8282\u4E2D\uFF0C\u6211\u4EEC\u5BF9\u5355\u4E2A\u4E8B\u4EF6\u54CD\u5E94\u5668\u8FDB\u884C\u4E86\u7B80\u5355\u6D4B\u8BD5\u3002\u4F46\u662F\u5728\u5B9E\u9645\u573A\u666F\u4E2D\uFF0C\u673A\u5668\u4EBA\u53EF\u80FD\u5B9A\u4E49\u4E86\u591A\u4E2A\u4E8B\u4EF6\u54CD\u5E94\u5668\uFF0C\u7531\u4E8E\u4F18\u5148\u7EA7\u548C\u54CD\u5E94\u89C4\u5219\u7684\u5B58\u5728\uFF0C\u9884\u671F\u7684\u4E8B\u4EF6\u54CD\u5E94\u5668\u53EF\u80FD\u5E76\u4E0D\u4F1A\u88AB\u89E6\u53D1\u3002NoneBug \u652F\u6301\u540C\u65F6\u6D4B\u8BD5\u591A\u4E2A\u4E8B\u4EF6\u54CD\u5E94\u5668\uFF0C\u4EE5\u6B64\u6765\u6D4B\u8BD5\u673A\u5668\u4EBA\u7684\u6574\u4F53\u884C\u4E3A\u3002"}),"\n",(0,r.jsx)(n.h2,{id:"\u6D4B\u8BD5\u4E8B\u4EF6\u54CD\u5E94",children:"\u6D4B\u8BD5\u4E8B\u4EF6\u54CD\u5E94"}),"\n",(0,r.jsxs)(n.p,{children:["NoneBug \u63D0\u4F9B\u4E86\u516D\u79CD\u5B9A\u4E49 ",(0,r.jsx)(n.code,{children:"Rule"})," \u548C ",(0,r.jsx)(n.code,{children:"Permission"})," \u9884\u671F\u884C\u4E3A\u7684\u65B9\u6CD5\uFF1A"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.code,{children:"should_pass_rule"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.code,{children:"should_not_pass_rule"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.code,{children:"should_ignore_rule"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.code,{children:"should_pass_permission"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.code,{children:"should_not_pass_permission"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.code,{children:"should_ignore_permission"})}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{title:"\u63D0\u793A",type:"tip",children:(0,r.jsxs)(n.p,{children:["\u4E8B\u4EF6\u54CD\u5E94\u5668\u7C7B\u578B\u7684\u68C0\u67E5\u5C5E\u4E8E ",(0,r.jsx)(n.code,{children:"Permission"})," \u7684\u4E00\u90E8\u5206\uFF0C\u56E0\u6B64\u53EF\u4EE5\u901A\u8FC7 ",(0,r.jsx)(n.code,{children:"should_pass_permission"})," \u548C ",(0,r.jsx)(n.code,{children:"should_not_pass_permission"})," \u65B9\u6CD5\u6765\u65AD\u8A00\u4E8B\u4EF6\u54CD\u5E94\u5668\u7C7B\u578B\u7684\u68C0\u67E5\u3002"]})}),"\n",(0,r.jsx)(n.p,{children:"\u4E0B\u9762\u6211\u4EEC\u6839\u636E\u63D2\u4EF6\u793A\u4F8B\u6765\u6D4B\u8BD5\u4E8B\u4EF6\u54CD\u5E94\u884C\u4E3A\uFF0C\u6211\u4EEC\u9996\u5148\u5B9A\u4E49\u4E24\u4E2A\u4E8B\u4EF6\u54CD\u5E94\u5668\u4F5C\u4E3A\u6D4B\u8BD5\u7684\u5BF9\u8C61\uFF1A"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",metastring:"title=example.py",children:'from nonebot import on_command\n\ndef never_pass():\n return False\n\nfoo = on_command("foo")\nbar = on_command("bar", permission=never_pass)\n'})}),"\n",(0,r.jsxs)(n.p,{children:["\u5728\u8FD9\u4E24\u4E2A\u4E8B\u4EF6\u54CD\u5E94\u5668\u4E2D\uFF0C",(0,r.jsx)(n.code,{children:"foo"})," \u5F53\u6536\u5230 ",(0,r.jsx)(n.code,{children:"/foo"}
1)," \u6D88\u606F\u65F6\u4F1A\u6267\u884C\uFF0C\u800C ",(0,r.jsx)(n.code,{children:"bar"})," \u5219\u4E0D\u4F1A\u6267\u884C\u3002\u6211\u4EEC\u4F7F\u7528 NoneBug \u6765\u6D4B\u8BD5\u5B83\u4EEC\uFF1A"]}),"\n",(0,r.jsxs)(a.A,{groupId:"testScope",children:[(0,r.jsxs)(i.A,{value:"separate",label:"\u72EC\u7ACB\u6D4B\u8BD5",default:!0,children:[(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",metastring:"{21,22,28,29} title=tests/test_example.py",children:'from datetime import datetime\n\nimport pytest\nfrom nonebug import App\nfrom nonebot.adapters.console import User, Message, MessageEvent\n\ndef make_event(message: str = "") -> MessageEvent:\n return MessageEvent(\n time=datetime.now(),\n self_id="test",\n message=Message(message),\n user=User(id="user"),\n )\n\[email protected]\nasync def test_example(app: App):\n from awesome_bot.plugins.example import foo, bar\n\n async with app.test_matcher(foo) as ctx:\n bot = ctx.create_bot()\n event = make_event("/foo")\n ctx.receive_event(bot, event)\n ctx.should_pass_rule()\n ctx.should_pass_permission()\n\n async with app.test_matcher(bar) as ctx:\n bot = ctx.create_bot()\n event = make_event("/foo")\n ctx.receive_event(bot, event)\n ctx.should_not_pass_rule()\n ctx.should_not_pass_permission()\n'})}),(0,r.jsxs)(n.p,{children:["\u5728\u4E0A\u9762\u7684\u4EE3\u7801\u4E2D\uFF0C\u6211\u4EEC\u5206\u522B\u5BF9 ",(0,r.jsx)(n.code,{children:"foo"})," \u548C ",(0,r.jsx)(n.code,{children:"bar"})," \u4E8B\u4EF6\u54CD\u5E94\u5668\u8FDB\u884C\u54CD\u5E94\u6D4B\u8BD5\u3002\u6211\u4EEC\u4F7F\u7528 ",(0,r.jsx)(n.code,{children:"ctx.should_pass_rule"})," \u548C ",(0,r.jsx)(n.code,{children:"ctx.should_pass_permission"})," \u65AD\u8A00 ",(0,r.jsx)(n.code,{children:"foo"})," \u4E8B\u4EF6\u54CD\u5E94\u5668\u5E94\u8BE5\u88AB\u89E6\u53D1\uFF0C\u4F7F\u7528 ",(0,r.jsx)(n.code,{children:"ctx.should_not_pass_rule"})," \u548C ",(0,r.jsx)(n.code,{children:"ctx.should_not_pass_permission"})," \u65AD\u8A00 ",(0,r.jsx)(n.code,{children:"bar"})," \u4E8B\u4EF6\u54CD\u5E94\u5668\u5E94\u8BE5\u88AB\u5FFD\u7565\u3002"]})]}),(0,r.jsxs)(i.A,{value:"global",label:"\u96C6\u6210\u6D4B\u8BD5",children:[(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",metastring:"title=tests/test_example.py",children:'from datetime import datetime\n\nimport pytest\nfrom nonebug import App\nfrom nonebot.adapters.console import User, Message, MessageEvent\n\ndef make_event(message: str = "") -> MessageEvent:\n return MessageEvent(\n time=datetime.now(),\n self_id="test",\n message=Message(message),\n user=User(id="user"),\n )\n\[email protected]\nasync def test_example(app: App):\n from awesome_bot.plugins.example import foo, bar\n\n async with app.test_matcher() as ctx:\n bot = ctx.create_bot()\n event = make_event("/foo")\n ctx.receive_event(bot, event)\n ctx.should_pass_rule(foo)\n ctx.should_pass_permission(foo)\n ctx.should_not_pass_rule(bar)\n ctx.should_not_pass_permission(bar)\n'})}),(0,r.jsxs)(n.p,{children:["\u5728\u4E0A\u9762\u7684\u4EE3\u7801\u4E2D\uFF0C\u6211\u4EEC\u5BF9 ",(0,r.jsx)(n.code,{children:"foo"})," \u548C ",(0,r.jsx)(n.code,{children:"bar"})," \u4E8B\u4EF6\u54CD\u5E94\u5668\u4E00\u8D77\u8FDB\u884C\u54CD\u5E94\u6D4B\u8BD5\u3002\u6211\u4EEC\u4F7F\u7528 ",(0,r.jsx)(n.code,{children:"ctx.should_pass_rule"})," \u548C ",(0,r.jsx)(n.code,{children:"ctx.should_pass_permission"})," \u65AD\u8A00 ",(0,r.jsx)(n.code,{children:"foo"})," \u4E8B\u4EF6\u54CD\u5E94\u5668\u5E94\u8BE5\u88AB\u89E6\u53D1\uFF0C\u4F7F\u7528 ",(0,r.jsx)(n.code,{children:"ctx.should_not_pass_rule"})," \u548C ",(0,r.jsx)(n.code,{children:"ctx.should_not_pass_permission"})," \u65AD\u8A00 ",(0,r.jsx)(n.code,{children:"bar"})," \u4E8B\u4EF6\u54CD\u5E94\u5668\u5E94\u8BE5\u88AB\u5FFD\u7565\u3002\u901A\u8FC7\u53C2\u6570\uFF0C\u6211\u4EEC\u53EF\u4EE5\u6307\u5B9A\u65AD\u8A00\u7684\u4E8B\u4EF6\u54CD\u5E94\u5668\u3002"]})]})]}),"\n",(0,r.jsxs)(n.p,{children:["\u5F53\u7136\uFF0C\u5982\u679C\u9700\u8981\u5FFD\u7565\u67D0\u4E2A\u4E8B\u4EF6\u54CD\u5E94\u5668\u7684\u54CD\u5E94\u89C4\u5219\u548C\u6743\u9650\u68C0\u67E5\uFF0C\u5F3A\u884C\u8FDB\u5165\u54CD\u5E94\u6D41\u7A0B\uFF0C\u6211\u4EEC\u53EF\u4EE5\u4F7F\u7528 ",(0,r.jsx)(n.code,{children:"should_ignore_rule"})," \u548C ",(0,r.jsx)(n.code,{children:"should_ignore_permission"})," \u65B9\u6CD5\uFF1A"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",metastring:"{21,22} title=tests/test_example.py",children:'from datetime import datetime\n\nimport pytest\nfrom nonebug import App\nfrom nonebot.adapters.console import User, Message, MessageEvent\n\ndef make_event(message: str = "") -> MessageEvent:\n return MessageEvent(\n time=datetime.now(),\n self_id="test",\n message=Message(message),\n user=User(id="user"),\n )\n\[email protected]\nasync def test_example(app: App):\n from awesome_bot.plugins.example import foo, bar\n\n async with app.test_matcher(bar) as ctx:\n bot = ctx.create_bot()\n event = make_event("/foo")\n ctx.receive_event(bot, event)\n ctx.should_ignore_rule(bar)\n ctx.should_ignore_permission(bar)\n'})}),"\n",(0,r.jsxs)(n.p,{children:["\u5728\u5FFD\u7565\u4E86\u54CD\u5E94\u89C4\u5219\u548C\u6743\u9650\u68C0\u67E5\u4E4B\u540E\uFF0C\u5C31\u4F1A\u8FDB\u5165 ",(0,r.jsx)(n.code,{children:"bar"})," \u4E8B\u4EF6\u54CD\u5E94\u5668\u7684\u54CD\u5E94\u6D41\u7A0B\u3002"]}),"\n",(0,r.jsx)(n.h2,{id:"\u6D4B\u8BD5\u5E73\u53F0\u63A5\u53E3\u4F7F\u7528",children:"\u6D4B\u8BD5\u5E73\u53F0\u63A5\u53E3\u4F7F\u7528"}),"\n",(0,r.jsxs)(n.p,{children:["\u4E0A\u4E00\u8282\u7684\u793A\u4F8B\u63D2\u4EF6\u6D4B\u8BD5\u4E2D\uFF0C\u6211\u4EEC\u5DF2\u7ECF\u5C1D\u8BD5\u4E86\u6D4B\u8BD5\u63D2\u4EF6\u5BF9\u4E8B\u4EF6\u7684\u6D88\u606F\u56DE\u590D\u3002\u901A\u5E38\u60C5\u51B5\u4E0B\uFF0C\u4E8B\u4EF6\u5904\u7406\u6D41\u7A0B\u4E2D\u5BF9\u5E73\u53F0\u63A5\u53E3\u7684\u4F7F\u7528\u4F1A\u901A\u8FC7\u4E8B\u4EF6\u54CD\u5E94\u5668\u64CD\u4F5C\u6216\u8005\u8C03\u7528\u5E73\u53F0 API \u4E24\u79CD\u9014\u5F84\u8FDB\u884C\u3002\u9488\u5BF9\u8FD9\u4E24\u79CD\u9014\u5F84\uFF0CNoneBug \u5206\u522B\u63D0\u4F9B\u4E86 ",(0,r.jsx)(n.code,{children:"ctx.should_call_send"})," \u548C ",(0,r.jsx)(n.code,{children:"ctx.should_call_api"})," \u65B9\u6CD5\u6765\u6D4B\u8BD5\u5E73\u53F0\u63A5\u53E3\u7684\u4F7F\u7528\u60C5\u51B5\u3002"]}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.code,{children:"should_call_send"})}),"\n",(0,r.jsxs)(n.p,{children:["\u5B9A\u4E49\u4E8B\u4EF6\u54CD\u5E94\u5668\u9884\u671F\u53D1\u9001\u7684\u6D88\u606F\uFF0C\u5373\u901A\u8FC7",(0,r.jsx)(n.a,{href:"/docs/appendices/session-control#send",children:"\u4E8B\u4EF6\u54CD\u5E94\u5668\u64CD\u4F5C send"}),"\u8FDB\u884C\u7684\u64CD\u4F5C\u3002",(0,r.jsx)(n.code,{children:"should_call_send"})," \u6709\u56DB\u4E2A\u53C2\u6570\uFF1A"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"event"}),"\uFF1A\u56DE\u590D\u7684\u76EE\u6807\u4E8B\u4EF6\u3002"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"message"}),"\uFF1A\u9884\u671F\u7684\u6D88\u606F\u5BF9\u8C61\uFF0C\u53EF\u4EE5\u662F ",(0,r.jsx)(n.code,{children:"str"}),"\u3001",(0,r.jsx)(n.code,{children:"Message"})," \u6216 ",(0,r.jsx)(n.code,{children:"MessageSegment"}),"\u3002"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"result"}),"\uFF1Asend \u7684\u8FD4\u56DE\u503C\uFF0C\u5C06\u4F1A\u8FD4\u56DE\u7ED9\u
163D2\u4EF6\u3002"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"bot"}),"\uFF08\u53EF\u9009\uFF09\uFF1A\u53D1\u9001\u6D88\u606F\u7684 bot \u5BF9\u8C61\u3002"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"**kwargs"}),"\uFF1Asend \u65B9\u6CD5\u7684\u989D\u5916\u53C2\u6570\u3002"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"should_call_api"}),"\n\u5B9A\u4E49\u4E8B\u4EF6\u54CD\u5E94\u5668\u9884\u671F\u8C03\u7528\u7684\u5E73\u53F0 API \u63A5\u53E3\uFF0C\u5373\u901A\u8FC7",(0,r.jsx)(n.a,{href:"/docs/appendices/api-calling#%E8%B0%83%E7%94%A8%E5%B9%B3%E5%8F%B0-api",children:"\u8C03\u7528\u5E73\u53F0 API"}),"\u8FDB\u884C\u7684\u64CD\u4F5C\u3002",(0,r.jsx)(n.code,{children:"should_call_api"})," \u6709\u56DB\u4E2A\u53C2\u6570\uFF1A"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"api"}),"\uFF1AAPI \u540D\u79F0\u3002"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"data"}),"\uFF1A\u9884\u671F\u7684\u8BF7\u6C42\u6570\u636E\u3002"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"result"}),"\uFF1Acall_api \u7684\u8FD4\u56DE\u503C\uFF0C\u5C06\u4F1A\u8FD4\u56DE\u7ED9\u63D2\u4EF6\u3002"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"adapter"}),"\uFF08\u53EF\u9009\uFF09\uFF1A\u8C03\u7528 API \u7684\u5E73\u53F0\u9002\u914D\u5668\u5BF9\u8C61\u3002"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"**kwargs"}),"\uFF1Acall_api \u65B9\u6CD5\u7684\u989D\u5916\u53C2\u6570\u3002"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["\u4E0B\u9762\u662F\u4E00\u4E2A\u4F7F\u7528 ",(0,r.jsx)(n.code,{children:"should_call_send"})," \u548C ",(0,r.jsx)(n.code,{children:"should_call_api"})," \u65B9\u6CD5\u7684\u793A\u4F8B\uFF1A"]}),"\n",(0,r.jsxs)(n.p,{children:["\u6211\u4EEC\u5148\u5B9A\u4E49\u4E00\u4E2A\u6D4B\u8BD5\u63D2\u4EF6\uFF0C\u5728\u54CD\u5E94\u6D41\u7A0B\u4E2D\u5411\u7528\u6237\u53D1\u9001\u4E00\u6761\u6D88\u606F\u5E76\u8C03\u7528 ",(0,r.jsx)(n.code,{children:"Console"})," \u9002\u914D\u5668\u7684 ",(0,r.jsx)(n.code,{children:"bell"})," API\u3002"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",metastring:"{8,9} title=example.py",children:'from nonebot import on_command\nfrom nonebot.adapters.console import Bot\n\nfoo = on_command("foo")\n\[email protected]()\nasync def _(bot: Bot):\n await foo.send("message")\n await bot.bell()\n'})}),"\n",(0,r.jsx)(n.p,{children:"\u7136\u540E\u6211\u4EEC\u5BF9\u8BE5\u63D2\u4EF6\u8FDB\u884C\u6D4B\u8BD5\uFF1A"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",metastring:"title=tests/test_example.py",children:'from datetime import datetime\n\nimport pytest\nimport nonebot\nfrom nonebug import App\nfrom nonebot.adapters.console import Bot, User, Adapter, Message, MessageEvent\n\ndef make_event(message: str = "") -> MessageEvent:\n return MessageEvent(\n time=datetime.now(),\n self_id="test",\n message=Message(message),\n user=User(id="user"),\n )\n\[email protected]\nasync def test_example(app: App):\n from awesome_bot.plugins.example import foo\n\n async with app.test_matcher(foo) as ctx:\n # highlight-start\n adapter = nonebot.get_adapter(Adapter)\n bot = ctx.create_bot(base=Bot, adapter=adapter)\n # highlight-end\n event = make_event("/foo")\n ctx.receive_event(bot, event)\n # highlight-start\n ctx.should_call_send(event, "message", result=None, bot=bot)\n ctx.should_call_api("bell", {}, result=None, adapter=adapter)\n # highlight-end\n'})}),"\n",(0,r.jsxs)(n.p,{children:["\u8BF7\u6CE8\u610F\uFF0C\u5BF9\u4E8E\u5728\u4F9D\u8D56\u6CE8\u5165\u4E2D\u4F7F\u7528\u4E86\u975E\u57FA\u7C7B\u5BF9\u8C61\u7684\u60C5\u51B5\uFF0C\u6211\u4EEC\u9700\u8981\u5728 ",(0,r.jsx)(n.code,{children:"create_bot"})," \u65B9\u6CD5\u4E2D\u6307\u5B9A ",(0,r.jsx)(n.code,{children:"base"})," \u548C ",(0,r.jsx)(n.code,{children:"adapter"})," \u53C2\u6570\uFF0C\u786E\u4FDD\u4E0D\u4F1A\u56E0\u4E3A\u91CD\u8F7D\u529F\u80FD\u800C\u51FA\u73B0\u975E\u9884\u671F\u60C5\u51B5\u3002"]}),"\n",(0,r.jsx)(n.h2,{id:"\u6D4B\u8BD5\u4F1A\u8BDD\u63A7\u5236",children:"\u6D4B\u8BD5\u4F1A\u8BDD\u63A7\u5236"}),"\n",(0,r.jsxs)(n.p,{children:["\u5728",(0,r.jsx)(n.a,{href:"/docs/appendices/session-control",children:"\u4F1A\u8BDD\u63A7\u5236"}),"\u4E00\u8282\u4E2D\uFF0C\u6211\u4EEC\u4ECB\u7ECD\u4E86\u5982\u4F55\u4F7F\u7528\u4E8B\u4EF6\u54CD\u5E94\u5668\u64CD\u4F5C\u6765\u5B9E\u73B0\u5BF9\u7528\u6237\u7684\u4EA4\u4E92\u5F0F\u4F1A\u8BDD\u3002\u5728\u4E0A\u4E00\u8282\u7684\u793A\u4F8B\u63D2\u4EF6\u6D4B\u8BD5\u4E2D\uFF0C\u6211\u4EEC\u5176\u5B9E\u5DF2\u7ECF\u4F7F\u7528\u4E86 ",(0,r.jsx)(n.code,{children:"ctx.should_finished"})," \u6765\u65AD\u8A00\u4F1A\u8BDD\u7ED3\u675F\u3002NoneBug \u9488\u5BF9\u5404\u79CD\u6D41\u7A0B\u63A7\u5236\u64CD\u4F5C\u5206\u522B\u63D0\u4F9B\u4E86\u76F8\u5E94\u7684\u65B9\u6CD5\u6765\u5B9A\u4E49\u9884\u671F\u7684\u4F1A\u8BDD\u5904\u7406\u884C\u4E3A\u3002\u5B83\u4EEC\u5206\u522B\u662F\uFF1A"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"should_finished"}),"\uFF1A\u65AD\u8A00\u4F1A\u8BDD\u7ED3\u675F\uFF0C\u5BF9\u5E94 ",(0,r.jsx)(n.code,{children:"matcher.finish"})," \u64CD\u4F5C\u3002"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"should_rejected"}),"\uFF1A\u65AD\u8A00\u4F1A\u8BDD\u7B49\u5F85\u7528\u6237\u8F93\u5165\u5E76\u91CD\u65B0\u6267\u884C\u5F53\u524D\u4E8B\u4EF6\u5904\u7406\u51FD\u6570\uFF0C\u5BF9\u5E94 ",(0,r.jsx)(n.code,{children:"matcher.reject"})," \u7CFB\u5217\u64CD\u4F5C\u3002"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"should_paused"}),": \u65AD\u8A00\u4F1A\u8BDD\u7B49\u5F85\u7528\u6237\u8F93\u5165\u5E76\u6267\u884C\u4E0B\u4E00\u4E2A\u4E8B\u4EF6\u5904\u7406\u51FD\u6570\uFF0C\u5BF9\u5E94 ",(0,r.jsx)(n.code,{children:"matcher.pause"})," \u64CD\u4F5C\u3002"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"\u6211\u4EEC\u4EC5\u9700\u5728\u6D4B\u8BD5\u7528\u4F8B\u4E2D\u7684\u6B63\u786E\u4F4D\u7F6E\u8
1C03\u7528\u8FD9\u4E9B\u65B9\u6CD5\uFF0C\u5C31\u53EF\u4EE5\u65AD\u8A00\u4F1A\u8BDD\u7684\u9884\u671F\u884C\u4E3A\u3002\u4F8B\u5982\uFF1A"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",metastring:"title=example.py",children:'from nonebot import on_command\nfrom nonebot.typing import T_State\n\nfoo = on_command("foo")\n\[email protected]("key", prompt="\u8BF7\u8F93\u5165\u5BC6\u7801")\nasync def _(state: T_State, key: str = ArgPlainText()):\n if key != "some password":\n try_count = state.get("try_count", 1)\n if try_count >= 3:\n await foo.finish("\u5BC6\u7801\u9519\u8BEF\u6B21\u6570\u8FC7\u591A")\n else:\n state["try_count"] = try_count + 1\n await foo.reject("\u5BC6\u7801\u9519\u8BEF\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165")\n await foo.finish("\u5BC6\u7801\u6B63\u786E")\n'})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",metastring:"title=tests/test_example.py",children:'from datetime import datetime\n\nimport pytest\nfrom nonebug import App\nfrom nonebot.adapters.console import User, Message, MessageEvent\n\ndef make_event(message: str = "") -> MessageEvent:\n return MessageEvent(\n time=datetime.now(),\n self_id="test",\n message=Message(message),\n user=User(id="user"),\n )\n\[email protected]\nasync def test_example(app: App):\n from awesome_bot.plugins.example import foo\n\n async with app.test_matcher(foo) as ctx:\n bot = ctx.create_bot()\n event = make_event("/foo")\n ctx.receive_event(bot, event)\n ctx.should_call_send(event, "\u8BF7\u8F93\u5165\u5BC6\u7801", result=None)\n ctx.should_rejected(foo)\n event = make_event("wrong password")\n ctx.receive_event(bot, event)\n ctx.should_call_send(event, "\u5BC6\u7801\u9519\u8BEF\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165", result=None)\n ctx.should_rejected(foo)\n event = make_event("wrong password")\n ctx.receive_event(bot, event)\n ctx.should_call_send(event, "\u5BC6\u7801\u9519\u8BEF\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165", result=None)\n ctx.should_rejected(foo)\n event = make_event("wrong password")\n ctx.receive_event(bot, event)\n ctx.should_call_send(event, "\u5BC6\u7801\u9519\u8BEF\u6B21\u6570\u8FC7\u591A", result=None)\n ctx.should_finished(foo)\n'})})]})}function u(e={}){let{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},90118(e,n,s){s.d(n,{OC:()=>p,O_:()=>x,uc:()=>m,vT:()=>d});var t=s(62540),r=s(63696),o=s(49519),a=s(92882),i=s(76274),l=s(635),c=s(56113);function d(e){return r.Children.toArray(e).filter(e=>"\n"!==e)}function h({value:e,tabValues:n}){return n.some(n=>n.value===e)}function p(e){let n,{defaultValue:s,queryString:t=!1,groupId:d}=e,p=function(e){let{values:n,children:s}=e;return(0,r.useMemo)(()=>{let e=n??r.Children.toArray(s).flatMap(e=>{if(!e)return[];if((0,r.isValidElement)(e)&&function(e){let{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return[e];let n="string"==typeof e.type?e.type:e.type.name;throw Error(`Docusaurus error: Bad <Tabs> child <${n}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop. 2If you do not want to pass on a "value" prop to the direct children of <Tabs>, you can also pass an explicit <Tabs values={...}> prop.`)}).map(({props:{value:e,label:n,attributes:s,default:t}})=>({value:e,label:n,attributes:s,default:t})),t=(0,l.XI)(e,(e,n)=>e.value===n.value);if(t.length>0)throw Error(`Docusaurus error: Duplicate values "${t.map(e=>`'${e.value}'`).join(", ")}" found in <Tabs>. Every value needs to be unique.`);return e},[n,s])}(e),[u,m]=(0,r.useState)(()=>(function({defaultValue:e,tabValues:n}){if(0===n.length)throw Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!h({value:e,tabValues:n}))throw Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${n.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}let s=n.find(e=>e.default)??n[0];if(!s)throw Error("Unexpected error: 0 tabValues");return s.value})({defaultValue:s,tabValues:p})),[x,_]=function({queryString:e=!1,groupId:n}){let s=(0,o.W6)(),t=function({queryString:e=!1,groupId:n}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!n)throw Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:e,groupId:n});return[(0,i.aZ)(t),(0,r.useCallback)(e=>{if(!t)return;let n=new URLSearchParams(s.location.search);n.set(t,e),s.replace({...s.location,search:n.toString()})},[t,s])]}({queryString:t,groupId:d}),[f,j]=function({groupId:e}){let n=e?`docusaurus.tab.${e}`:null,[s,t]=(0,c.Dv)(n);return[s,(0,r.useCallback)(e=>{n&&t.set(e)},[n,t])]}({groupId:d}),b=h({value:n=x??f,tabValues:p})?n:null;return(0,a.A)(()=>{b&&m(b)},[b]),{selectedValue:u,selectValue:(0,r.useCallback)(e=>{if(!h({value:e,tabValues:p}))throw Error(`Can't select invalid tab value=${e}`);m(e),_(e),j(e)},[_,j,p]),tabValues:p,lazy:e.lazy??!1,block:e.block??!1}}let u=(0,r.createContext)(null);function m(){let e=r.useContext(u);if(!e)throw Error("useTabsContext() must be used within a Tabs component");return e}function x(e){return(0,t.jsx)(u.Provider,{value:e.value,children:e.children})}},84993(e,n,s){s.d(n,{A:()=>i});var t=s(62540);s(63696);var r=s(11750),o=s(90118);function a({children:e,className:n,hidden:s}){return(0,t.jsx)("div",{role:"tabpanel",className:(0,r.A)("tab-panel",n),hidden:s,children:e})}function i({children:e,className:n,value:s}){let{selectedValue:r,lazy:l}=(0,o.uc)(),c=s===r;return!c&&l?null:(0,t.jsx)(a,{className:n,hidden:!c,children:e})}},36031(e,n,s){s.d(n,{A:()=>p});var t=s(62540);s(63696);var r=s(11750),o=s(49130),a=s(90118),i=s(72489),l=s(48682);function c({className:e}){let{selectedValue:n,selectValue:s,tabValues:o,block:l}=(0,a.uc)(),d=[],{blockElementScrollPositionUntilNextRender:h}=(0,i.a_)(),p=e=>{let t=e.currentTarget,r=o[d.indexOf(t)].value;r!==n&&(h(t),s(r))},u=e=>{let n=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{let s=d.indexOf(e.currentTarget)+1;n=d[s]??d[0];break}case"ArrowLeft":{let s=d.indexOf(e.currentTarget)-1;n=d[s]??d[d.length-1]}}n?.focus()};return(0,t.jsx)("div",{className:"not-prose",children:(0,t.jsxs)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.A)("tabs tabs-list tabs-lifted",l&&"tabs-block",e),children:[o.map(({value:e,label:s,attributes:o})=>(0,t.jsx)("li",{role:"tab",tabIndex:n===e?0:-1,"aria-selected":n===e,ref:e=>{d.push(e)},onKeyDown:u,onClick:p,...o,className:(0,r.A)("tab tab-lifted tab-item",o?.className,n===e&&"tab-active tab-item-active"),children:s??e},e)),(0,t.jsx)("div",{className:"tab tab-lifted tab-item tab-spacer"})]})})}function d({children:e}){return(0,t.jsx)("div",{children:e})}function h({className:e,children:n}){return(0,t.jsxs)("div",{className:(0,r.A)(o.G.tabs.container,"tabs-container"),children:[(0,t.jsx)(c,{className:e}),(0,t.jsx)(d,{children:n})]})}function p(e){let n=(0,l.A)(),s=(0,a.OC)(e);return(0,t.jsx)(a.O_,{value:s,children:(0,t.jsx)(h,{className:e.className,children:(0,a.vT)(e.children)})},String(n))}},43023(e,n,s){s.d(n,{R:()=>a,x:()=>i});var t=s(63696);let r={},o=t.createContext(r);function a(e){let n=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]);
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.