I adapted the addition function from examples folder into a class so I could move command functionality into a separate module. It's in cogs/addition.py:
from discord.ext import commands
class Math:
def __init__(self, bot):
self.bot = bot
@commands.command()
async def add(self, left: int, right: int):
"""Adds two numbers together."""
await self.bot.say(left + right)
def setup(bot):
bot.add_cog(Math(bot))
How would I go about testing the add function? I tried the following code:
from cogs import addition
from discord.ext import commands
bot = commands.Bot(command_prefix='.', description='None')
def test_coin_flip():
cl = addition.Math(bot)
assert cl.add(5, 4) == 9
but once I run it I get TypeError:
============================= test session starts =============================
platform win32 -- Python 3.5.1, pytest-2.8.1, py-1.4.30, pluggy-0.3.1
rootdir: D:\Dev\discord-cloudbot\tests, inifile:
collected 1 items
D:\Dev\discord-cloudbot\tests\test_cogs.py F
def test_coin_flip():
cl = addition.Math(bot)
> assert cl.add(5, 4) == 9
E TypeError: 'Command' object is not callable
I'd be impressed if you could unit test a bot that requires an external service as input.
To get the wrapped function from a Command object you use Command.callback (this will be unbound) And you can pass arguments directly in this case.
You can also call Command.invoke(ctx) to call the bound method (which is probably what you want.) This will also run any checks bound to the command as well. You would have to build up a Context object and cannot pass arguments directly.
e.g
cog = MyCog()
ctx = Context(fake_context_params...)
result = cog.my_command.invoke(ctx)
# or
result = cog.my_command.callback(cog, args...)
Note that in your example, your add command doesn't return anything, it calls bot.say - which is different. Make sure you understand what you're trying to test - testing something like this will require a fair bit of mocking. You'd be better off separating your logic and testing that unit separately, rather than testing commands directly.
You'd be better off separating your logic and testing that unit separately, rather than testing commands directly.
Yeah, that's exactly what I need to do. A momentary lapse of judgement from my part.
Not related to this repo, but someone on the discord just brought this to my attention, might work as a solution for now. I'm going to check it out.
https://github.com/DXsmiley/dismock
I'd be impressed if you could unit test a bot that requires an external service as input.
boy do I have news for you
Most helpful comment
boy do I have news for you