Crates.io | teloxide_tests |
lib.rs | teloxide_tests |
version | 0.2.0 |
source | src |
created_at | 2024-07-17 15:50:16.42202 |
updated_at | 2024-09-20 15:04:52.631506 |
description | Test suite for teloxide bots |
homepage | |
repository | https://github.com/LasterAlex/teloxide_tests |
max_upload_size | |
id | 1306296 |
size | 263,890 |
teloxide_tests
A crate that allows you to unit test your teloxide bots easily! No internet, accounts or anything required!
me
and multiple updates (see album_bot)Simplified [hello_world_bot
]
#[tokio::test]
async fn test_hello_world() {
let message = MockMessageText::new().text("Hi!");
let bot = MockBot::new(message, handler_tree());
// Sends the message as if it was from a user
bot.dispatch().await;
let responses = bot.get_responses();
let message = responses
.sent_messages
.last()
.expect("No sent messages were detected!");
assert_eq!(message.text(), Some("Hello World!"));
}
#[tokio::test]
async fn test_not_a_document() {
let bot = MockBot::new(MockMessageText::new().text("Hi!"), handler_tree());
// Syntactic sugar
bot.dispatch_and_check_last_text("Not a document").await;
}
#[tokio::test]
async fn test_download_document_and_check() {
let bot = MockBot::new(MockMessageDocument::new(), handler_tree());
bot.dispatch_and_check_last_text("Downloaded!").await;
}
#[tokio::test]
async fn test_what_is_the_first_number() {
let bot = MockBot::new(MockCallbackQuery::new().data("add"), handler_tree());
bot.dependencies(deps![get_bot_storage().await]);
bot.set_state(State::WhatDoYouWant).await;
bot.dispatch_and_check_last_text_and_state(
text::ENTER_THE_FIRST_NUMBER,
State::GetFirstNumber {
operation: "add".to_owned(),
},
)
.await;
}
You can see more useful examples at examples/ and the docs at docs.rs
It is highly reccomended you read at least hello_world_bot
(there is a lot of comments that explain how to use this crate which i removed in the README) and calculator_bot
(it teaches about the syntactic sugar and working with dialogue)
Hopefully it is as easy as doing what happens in ./examples
teloxide_tests
Do NOT use raw MockBot fields like bot.updates or bot.me to mutate the bot, unless you know what you are doing. Use given abstractions, and if some feature is missing, you can mention it in the github repo (or write it in the telegram group @teloxide_tests)
Race conditions. They are, to my knoledge, the most difficult.
And also when you use a method that is still not supported by this crate. Please reffer to the docs to see, what endpoints are implemented in the latest release (or look at server/routes files to look at the current endpoints)
Maybe also the fact that the fake server actually checks the messages and files that are present, and it starts with a clean state. You can't just send a file by file_id or forward a message by an arbitrary message_id that was sent long ago, the bot wouldn't know what to do with it, so you need to separately add it by dispatching the bot with that update, so that it gets added as the user message to memory (you can change file_id and message_id in the mocked structs to anything you need).
trait Send
is not implemented for std::sync::MutexGuard<'static, ()>
This means you can't share the bot between any threads, as you should not in any circumstance.
PoisonError(...)
You shouldn't see it, i tried to mitigate it, but if you do, it's not the problem, it just means that something else panicked and now the bot doesn't know, what to do. Just fix whatever was causing the problem, and poison errors should be gone.
Stupid bugs that change every time you run a test
You can use the crate serial_test, or try to add drop(bot);
at the end of every test, and do everything AFTER calling MockBot::new()
, as the bot creation makes a safe lock that prevent any race conditions.
Please see CONTRIBUTING.md
The teloxide team! They made an absolutely incredible library with amazing internal documentation, which helped me a lot during development! It is an amazing project, and i'm happy i'm able to add to it something useful!