Adott egy függvény és egy fejlesztői környezetbe épülő mesterséges intelligencia LLM (Large Language Model (Nagy Nyelvi Modell)), valamint a következő prompt: “write a test for this function”.

 1pub async fn create_inner<F, M>(
 2    claims: Claims,
 3    organizational_units_module: Arc<OrganizationalUnitsModule>,
 4    payload: Result<Json<CreateRequestHelper>, JsonRejection>,
 5    repo_factory: F,
 6    migrator_factory: M,
 7) -> Response
 8where
 9    F: Fn() -> Box<dyn OrganizationalUnitsRepository + Send + Sync>,
10    M: Fn() -> Box<dyn DatabaseMigrator + Send + Sync>,
11{
12    match payload {
13        Ok(Json(payload)) => match CreateRequest::try_from(payload) {
14            Ok(user_input) => {
15                let mut repo = repo_factory();
16                let migrator = migrator_factory();
17                match try_create(
18                    &mut *repo,
19                    &*migrator,
20                    claims,
21                    user_input,
22                    organizational_units_module
23                ).await
24                {
25                    Ok(resp) => (StatusCode::CREATED, Json(resp)).into_response(),
26                    Err(e) => e.into_response(),
27                }
28            }
29            Err(e) => e.into_response(),
30        },
31        Err(_) => FriendlyError::UserFacing(
32            StatusCode::BAD_REQUEST,
33            "ORGANIZATIONAL_UNITS/HANDLER/CREATE".to_string(),
34            "Invalid JSON".to_string(),
35        )
36            .trace(Level::DEBUG)
37            .into_response(),
38    }
39}

Erre a modelltől a következő válasz érkezik Link to heading

 1use axum::{body::Body, http::Response, response::IntoResponse, Json};
 2use std::sync::Arc;
 3use mockall::predicate::*;
 4use tokio_test::assert_eq; // for assertions
 5
 6#[tokio::test]
 7async fn test_create_inner_success() {
 8    // Arrange: Mocks
 9    let mut mock_repo = MockOrganizationalUnitsRepository::new();
10    let mut mock_migrator = MockDatabaseMigrator::new();
11
12    // Setup mock behavior for try_create
13    mock_repo.expect_setup_managed()
14        .times(1)
15        .returning(|_, _, _, _, _| Box::pin(async { Ok(/* your mock organizational unit */) }));
16
17    mock_migrator.expect_migrate_tenant_db()
18        .times(1)
19        .returning(|_| Box::pin(async { Ok(()) }));
20
21    // Define the repo_factory
22    let repo_factory = || Box::new(mock_repo.clone()) as Box<dyn OrganizationalUnitsRepository + Send + Sync>;
23
24    // Define the migrator factory
25    let migrator_factory = || Box::new(mock_migrator.clone()) as Box<dyn DatabaseMigrator + Send + Sync>;
26
27    // Fake claims, module, and payload
28    let claims = Claims { /* fill accordingly */ };
29    let organizational_units_module = Arc::new(OrganizationalUnitsModule { /* fill accordingly */ });
30    let payload = Ok(Json(CreateRequestHelper { /* fill accordingly */ }));
31
32    // Act
33    let response = create_inner(claims, organizational_units_module, payload, repo_factory, migrator_factory).await;
34
35    // Assert
36    assert_eq!(response.status(), StatusCode::CREATED);
37}
38
39// Additional tests for error scenarios, invalid JSON, etc., can follow a similar pattern.

A valóban működő megfejtés pedig valami ilyesmi lesz Link to heading

 1#[cfg(test)]
 2mod tests {
 3    use std::ops::Add;
 4    use std::time::Duration;
 5    use chrono::Local;
 6    use sqlx::postgres::PgPoolOptions;
 7    use uuid::Uuid;
 8    use crate::app::config::{AppConfig, BasicDatabaseConfig, DatabaseUrlProvider};
 9    use crate::app::database::{MockDatabaseMigrator, MockPgPoolManagerTrait};
10    use crate::organizational_units::model::OrganizationalUnit;
11    use crate::organizational_units::repository::MockOrganizationalUnitsRepository;
12    use super::*;
13
14    #[tokio::test]
15    async fn test_create_inner_success() {
16        let mut pool_manager_mock = MockPgPoolManagerTrait::new();
17        pool_manager_mock.expect_add_tenant_pool().times(1).returning(|tenant_id, _| Ok(tenant_id));
18        pool_manager_mock.expect_get_tenant_pool().times(1).returning(|_| {
19            let database_config = BasicDatabaseConfig::default();
20            Ok(Some(PgPoolOptions::new().connect_lazy(&database_config.url()).unwrap()))
21        });
22
23        let organizational_units_module = Arc::new(OrganizationalUnitsModule {
24            pool_manager: Arc::new(pool_manager_mock),
25            config: Arc::new(AppConfig::default()),
26        });
27
28        let payload = Ok(Json(CreateRequestHelper {
29            name: (String::from("test")),
30            is_self_hosted: false,
31            db_host: None,
32            db_port: None,
33            db_name: None,
34            db_user: None,
35            db_password: None,
36        }));
37
38        let repo_factory = || {
39            let mut repo = MockOrganizationalUnitsRepository::new();
40            repo.expect_setup_managed()
41                .times(1)
42                .withf(|_, name, _, _, _| name == "test")
43                .returning(|uuid: Uuid, _, _, _, _| {
44                    Ok(OrganizationalUnit {
45                        id: uuid,
46                        name: "test".to_string(),
47                        db_host: "localhost".to_string(),
48                        db_port: 5432,
49                        db_name: "database".to_string(),
50                        db_user: "user".to_string(),
51                        db_password: "password".to_string(),
52                        db_max_pool_size: 5,
53                        db_ssl_mode: "disable".to_string(),
54                        created_at: Local::now(),
55                        updated_at: Local::now(),
56                        deleted_at: None,
57                    })
58                });
59            Box::new(repo) as Box<dyn OrganizationalUnitsRepository + Send + Sync>
60        };
61
62        let migrator_factory = || {
63            let mut migrator = MockDatabaseMigrator::new();
64            migrator.expect_migrate_tenant_db()
65                .times(1)
66                .returning(|_| {
67                    Ok(())
68                });
69            Box::new(migrator) as Box<dyn DatabaseMigrator + Send + Sync>
70        };
71
72
73        let exp = Local::now().add(Duration::from_secs(100)).timestamp();
74        let iat = Local::now().timestamp();
75        let nbf = Local::now().timestamp();
76
77        let claims = Claims::new(
78            Uuid::new_v4().to_string(),
79            usize::try_from(exp).unwrap(),
80            usize::try_from(iat).unwrap(),
81            usize::try_from(nbf).unwrap(),
82            String::from("test_service"),
83            String::from("test_user"),
84            Uuid::new_v4().to_string(),
85        );
86
87        let response = create_inner(claims, organizational_units_module, payload, repo_factory, migrator_factory).await;
88
89        assert_eq!(response.status(), StatusCode::CREATED);
90    }
91}

Akkor végülis majdnem a felét eltalálta, nem? Link to heading

A mesterséges intelligencia LLM modellek olyan algoritmusok, amelyek hatalmas mennyiségű szöveges adat alapján tanulnak meg nyelvi mintákat. Ez különösen jól működik programkódok esetében, mert azok nagyon kötött szabályokat követnek, és a betanult mintákból egész jó eredményeket tudnak hozni, különösen akkor, ha sablonok generálásáról van szó.

A “mesterséges intelligencia” modellek könnyedén tudnak kezelni egyszerű feladatokat, de amikor összetettebb problémákat kell megoldani — melyekhez szükséges a kontextus megértése — akkor az élő fejlesztőknél az előny.

Dehát akkor végülis mégis megírta a kód majdnem felét, nem? Link to heading

A programkódok komplexitását nem a sorok száma határozza meg. Addig a pontig, ameddig az LLM eljutott, a betanult mintázatok visszaadásával el lehetett jutni, de a kód tényleges befejezéséhez sokkal mélyebb megértésre és teljesen más képességekre van szükség, mint amit egy LLM tud nyújtani.

Tehát akkor azoknak a fejlesztőknek a munkáját veszi majd ez el, akik kevésbé komplex dolgokon dolgoznak? Link to heading

Ennek a kérdésnek a megválaszolásához meg kell értenünk azt a folyamatot, ahogy a komplex problémákon dolgozó fejlesztők keletkeznek, ami a következő: adva van egy ember, aki fejlesztő szeretne lenni. Elkezd programokat írni, először kevésbé komplex problémákon dolgozva. Rájön, hogy ez nagyon tetszik neki, és sok-sok évet tölt el a kevésbé összetett problémákkal, miközben tapasztalatot gyűjt. Idővel egyre összetettebb problémákat tud megoldani, míg egy napon észreveszi, hogy ő az a fejlesztő, aki már a komplex feladatokon dolgozik.

Most, hogy értjük, hogyan keletkezik az összetett feladatokon dolgozó fejlesztő, áthelyezhetjük a kérdést vállalati környezetbe: ha a cégek nem foglalkoztatnak kezdő fejlesztőket, mert a mesterséges intelligencia LLM segítségével a tapasztalt fejlesztők megoldják a problémákat, akkor egy idő után nem lesznek tapasztalt fejlesztők. Lehet arra fogadni, hogy amire ez bekövetkezik, addigra elég fejlett lesz a mesterséges intelligencia, hogy a tapasztalt fejlesztőket is kiváltsa, de én erre nem tennék nagy téteket.