我正在尝试使用actix-web和sqlx设置一个 Web 应用程序,我可以在其中进行具有自己的 Web 服务器和数据库事务的测试。我尝试设置我的服务器创建,使其接受数据库(Postgres)池或使用Executor特征的事务。虽然我在编译应用程序代码和测试时遇到了一些问题:
// main.rs
use std::net::TcpListener;
use actix_web::dev::Server;
use actix_web::{web, App, HttpServer, Responder};
use sqlx::PgPool;
async fn create_pool() -> PgPool {
PgPool::connect("postgres://postgres:postgres@localhost:5432/postgres")
.await
.expect("Failed to create pool")
}
async fn index() -> impl Responder {
"Hello World!"
}
pub fn create_server<'a, E: 'static>(
listener: TcpListener,
pool: E,
) -> Result<Server, std::io::Error>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
{
let server = HttpServer::new(move || App::new().data(pool).route("/", web::get().to(index)))
.listen(listener)?
.run();
Ok(server)
}
pub async fn server(pool: PgPool) -> std::io::Result<()> {
const PORT: usize = 8088;
let listener =
TcpListener::bind(format!("0.0.0.0:{}", PORT)).expect("Failed to create listener");
println!("Running on port {}", PORT);
create_server(listener, pool).unwrap().await
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let pool = create_pool().await;
server(pool).await;
Ok(())
}
#[cfg(test)]
pub mod tests {
use super::*;
use std::net::TcpListener;
#[actix_rt::test]
async fn test_foo() {
let pool = create_pool().await;
let mut transaction = pool.begin().await.expect("Failed to create transaction");
let listener = TcpListener::bind("0.0.0.0:0").expect("Failed to create listener");
let server = create_server(listener, &mut transaction).expect("Failed to create server");
tokio::spawn(server);
}
}
# Cargo.toml
[package]
name = "sqlx-testing"
version = "0.1.0"
authors = ["Oskar"]
edition = "2018"
[dependencies]
actix-rt = "1.1.1"
actix-web = "3.3.2"
sqlx = { version = "0.4.2", default-features = false, features = ["postgres", "runtime-async-std-native-tls"] }
tokio = "0.2.22"
编译输出
error[E0277]: the trait bound `Pool<Postgres>: Executor<'_>` is not satisfied
--> src\main.rs:37:29
|
17 | pub fn create_server<'a, E: 'static>(
| ------------- required by a bound in this
...
22 | E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
| --------------------------------------------- required by this bound in `create_server`
...
37 | create_server(listener, pool).unwrap().await
| ^^^^ the trait `Executor<'_>` is not implemented for `Pool<Postgres>`
|
= help: the following implementations were found:
<&Pool<DB> as Executor<'p>>
error[E0277]: the trait bound `Pool<Postgres>: Copy` is not satisfied
--> src\main.rs:37:29
|
17 | pub fn create_server<'a, E: 'static>(
| ------------- required by a bound in this
...
22 | E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
| ---- required by this bound in `create_server`
...
37 | create_server(listener, pool).unwrap().await
| ^^^^ the trait `Copy` is not implemented for `Pool<Postgres>`