• 使用babyapi的简单示例创建初始main.go

  • 使用 CLI 生成测试样板

  • 通过用预期的 JSON 填充占位符来实现每个测试

  • 运行测试并查看它们是否通过!

  • 由于 PUT 是幂等的,因此需要包含所有字段。为了避免这种情况,我们希望添加对使用 PATCH 请求切换 Completed 的支持。我们首先添加一个简单的测试来了解我们期望此功能的外观

  • 此测试失败,因为babyapi默认不支持PATCH。我们可以通过为 TODO 结构实现 Patch 来修复它。由于我们通过两个测试定义了我们的功能,因此我们最简单的实现不仅仅是设置 Completed = true 并且我们必须使用请求中的值

  • 现在我们可以更改 TODO 的已完成状态,但我们仍然无法使用 PATCH 来修改其他字段,如这组新测试所示

  • 更新补丁以设置剩余字段

  • 我们的测试仍然失败,因为我们总是使用请求字段更新 TODO,即使它们是空的。通过更新实现来检查空值来修复此问题

  • 新的 UpdateWithPatch 测试通过,但我们之前的测试失败。由于我们将 Completed 更改为 *bool,因此使用空值创建的 TODO 将显示为 null

  • 为 TODO 实现渲染,这样我们就可以将 nil 视为 false

  • 通过测试驱动开发来实现 PATCH 功能,从而产生了一组强大的测试和良好实现的功能。由于我们首先在测试中定义 PATCH 请求的预期输入和输出,因此很容易看到由于不检查请求中的空值而导致的问题。此外,当将 Completed 类型更改为 *bool 时,我们预先存在的测试能够防止重大更改。

    结论

    测试驱动开发是创建经过充分测试的正确代码的有效方法。通过从测试开始,我们可以确保每段代码都被设计为可测试的,而不是让测试成为事后的想法。

    如果您对采用 TDD 犹豫不决,这里有一些可以开始的想法:

    即使 TDD 不太适合您编写代码的方式,它仍然是您随身携带的强大工具。我鼓励您至少花一些时间尝试一下,看看它如何影响您的开发过程。

    ","image":"http://www.luping.net/uploads/20240730/172232678666a89f02dc4a5.jpg","datePublished":"2024-07-30T16:06:26+08:00","dateModified":"2024-07-30T16:06:26+08:00","author":{"@type":"Person","name":"luping.net","url":"https://www.luping.net/articlelist/0_1.html"}}
    」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
    首頁 > 程式設計 > Go 中的測試驅動 API 開發

    Go 中的測試驅動 API 開發

    發佈於2024-07-30
    瀏覽:536

    Test-driven API Development in Go

    介绍

    测试驱动开发是确保代码经过良好测试和可重构的有效方法。基本思想是通过编写测试开始开发。这些测试清楚地记录了期望并为成功实施创建了标准。如果做得正确,您可以在编写任何代码之前清楚地定义函数的预期输入/输出。这有一些直接的好处:

    • 您仔细考虑与代码交互的界面并将其设计为可测试的
    • 当您开始编写代码时,您的流程不会因手动测试或单步执行执行逻辑来预测结果而中断。相反,您只需运行测试
    • 通过测试成为一个令人满意的目标。将流程分解为一系列明确且可实现的里程碑使工作变得更加愉快
    • 避免实施后的懒惰和过度自信,这可能会阻止您测试代码

    现在您已确信这些好处,您可以按照以下步骤开始测试驱动开发 (TDD):

    1. 编写或修改测试
    2. 检查测试是否失败
    3. 编写最少数量的代码以使测试通过

    这些步骤是循环执行的,因此您总是添加更多测试来挑战当前的实现。

    最后一步,指定编写最少量的代码,如果严格遵循,事情可能会变得乏味。在确定何时适合偏离该规则之前,了解该规则存在的原因非常重要。

    简单的例子

    您的任务是实现函数 Add(x, y int) int。在跳转到实现并返回 x y 之前,编写最简单的测试:1 1 == 2。那么,通过测试的最简单实现是什么?只是返回 2。现在你的测试通过了!

    此时,您意识到需要更多测试,因此您加快了步伐并添加了更多测试:

    • 1 2 == 3
    • 100 5 == 105

    现在您的测试失败了,因此您需要修复实现。这次你不能只返回 3 或返回 105,所以你需要找到一个适用于所有测试的解决方案。这导致了实现: return x y.

    虽然在这个简单的示例中这感觉过于乏味,但严格遵守此方法会导致您编写多个测试而不是仅仅信任您的实现。当然,您最初返回 x y 的想法是可行的,但重点是重新训练自己依赖测试而不是您自己对代码的理解。在现实世界中,您并不是唯一一个处理这段代码的人,并且不可避免地会忘记实现细节。这个过程迫使你编写更多的测试并思考更多的方法来打破简单的实现。

    最终,您将获得经验并学会找到适合您遇到的不同场景的平衡点。您将恢复全速实现功能,并发现错误更少并编写更多可维护的代码。

    HTTP API 的逐步 TDD

    让我们进入一个使用 TDD 实现 HTTP REST API 的更复杂的示例。本分步指南使用我的 Go 框架babyapi,但这些概念可以应用于任何地方。

    babyapi 使用泛型围绕 Go 结构创建完整的 CRUD API,从而使创建完整的 REST API 和客户端 CLI 变得非常容易。除此之外,babytest 包还提供了一些用于创建端到端 API 表测试的工具。在 API 级别使用 TDD 可以一次性全面测试新 API 或功能的 HTTP 和存储层。

    免责声明:由于babyapi 处理大部分实现并且还用于生成测试样板,因此从技术上讲我们并不是从TDD 开始。然而,我们将看到在我们的 API 中添加对 PATCH 请求的支持有多么有益。

    1. 创建一个新的Go项目

    2. 使用babyapi的简单示例创建初始main.go

    3. 使用 CLI 生成测试样板

    4. 通过用预期的 JSON 填充占位符来实现每个测试

    5. 运行测试并查看它们是否通过!

    6. 由于 PUT 是幂等的,因此需要包含所有字段。为了避免这种情况,我们希望添加对使用 PATCH 请求切换 Completed 的支持。我们首先添加一个简单的测试来了解我们期望此功能的外观

    7. 此测试失败,因为babyapi默认不支持PATCH。我们可以通过为 TODO 结构实现 Patch 来修复它。由于我们通过两个测试定义了我们的功能,因此我们最简单的实现不仅仅是设置 Completed = true 并且我们必须使用请求中的值

    8. 现在我们可以更改 TODO 的已完成状态,但我们仍然无法使用 PATCH 来修改其他字段,如这组新测试所示

    9. 更新补丁以设置剩余字段

    10. 我们的测试仍然失败,因为我们总是使用请求字段更新 TODO,即使它们是空的。通过更新实现来检查空值来修复此问题

    11. 新的 UpdateWithPatch 测试通过,但我们之前的测试失败。由于我们将 Completed 更改为 *bool,因此使用空值创建的 TODO 将显示为 null

    12. 为 TODO 实现渲染,这样我们就可以将 nil 视为 false

    通过测试驱动开发来实现 PATCH 功能,从而产生了一组强大的测试和良好实现的功能。由于我们首先在测试中定义 PATCH 请求的预期输入和输出,因此很容易看到由于不检查请求中的空值而导致的问题。此外,当将 Completed 类型更改为 *bool 时,我们预先存在的测试能够防止重大更改。

    结论

    测试驱动开发是创建经过充分测试的正确代码的有效方法。通过从测试开始,我们可以确保每段代码都被设计为可测试的,而不是让测试成为事后的想法。

    如果您对采用 TDD 犹豫不决,这里有一些可以开始的想法:

    • 在函数的输入/输出清晰且实现不太复杂的简单场景中尝试。您可以为可能遇到的各种输入/输出编写一个强大的表测试。清晰地了解不同的场景可以简化实施
    • 如果您正在修复新的错误,那么您已经在测试中发现了差距。首先编写一个可以首先识别此错误的测试。然后,在不破坏任何现有测试的情况下使该测试通过。
    • 与babyapi示例类似,您可以使用TDD进行高级API测试。一旦您定义了预期的请求/响应,您就可以恢复通常的开发流程,以实现更注重细节的部分

    即使 TDD 不太适合您编写代码的方式,它仍然是您随身携带的强大工具。我鼓励您至少花一些时间尝试一下,看看它如何影响您的开发过程。

    版本聲明 本文轉載於:https://dev.to/calvinmclean/test-driven-api-development-in-go-1fb8?1如有侵犯,請聯絡[email protected]刪除
    最新教學 更多>
    • 插入資料時如何修復「常規錯誤:2006 MySQL 伺服器已消失」?
      插入資料時如何修復「常規錯誤:2006 MySQL 伺服器已消失」?
      插入記錄時如何解決「一般錯誤:2006 MySQL 伺服器已消失」介紹:將資料插入MySQL 資料庫有時會導致錯誤「一般錯誤:2006 MySQL 伺服器已消失」。當與伺服器的連線遺失時會出現此錯誤,通常是由於 MySQL 配置中的兩個變數之一所致。 解決方案:解決此錯誤的關鍵是調整wait_tim...
      程式設計 發佈於2024-12-19
    • Bootstrap 4 Beta 中的列偏移發生了什麼事?
      Bootstrap 4 Beta 中的列偏移發生了什麼事?
      Bootstrap 4 Beta:列偏移的刪除和恢復Bootstrap 4 在其Beta 1 版本中引入了重大更改柱子偏移了。然而,隨著 Beta 2 的後續發布,這些變化已經逆轉。 從 offset-md-* 到 ml-auto在 Bootstrap 4 Beta 1 中, offset-md-*...
      程式設計 發佈於2024-12-19
    • 如何在 PHP 中組合兩個關聯數組,同時保留唯一 ID 並處理重複名稱?
      如何在 PHP 中組合兩個關聯數組,同時保留唯一 ID 並處理重複名稱?
      在 PHP 中組合關聯數組在 PHP 中,將兩個關聯數組組合成一個數組是常見任務。考慮以下請求:問題描述:提供的代碼定義了兩個關聯數組,$array1和$array2。目標是建立一個新陣列 $array3,它合併兩個陣列中的所有鍵值對。 此外,提供的陣列具有唯一的 ID,而名稱可能重疊。要求是建構一...
      程式設計 發佈於2024-12-19
    • 在 Go 中使用 WebSocket 進行即時通信
      在 Go 中使用 WebSocket 進行即時通信
      构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
      程式設計 發佈於2024-12-19
    • 儘管程式碼有效,為什麼 POST 請求無法擷取 PHP 中的輸入?
      儘管程式碼有效,為什麼 POST 請求無法擷取 PHP 中的輸入?
      解決PHP 中的POST 請求故障在提供的程式碼片段:action=''而非:action="<?php echo $_SERVER['PHP_SELF'];?>";?>"檢查$_POST陣列:表單提交後使用 var_dump 檢查 $_POST 陣列的內容...
      程式設計 發佈於2024-12-19
    • 使用“list.List”是建立帶有字串鍵和列表值的 Go 映射的最佳方法嗎?
      使用“list.List”是建立帶有字串鍵和列表值的 Go 映射的最佳方法嗎?
      建立字串到清單的對應問題:您想要建立一個有字串型別鍵的映射和列表類型的值。以下程式碼片段是否是正確的方法:package main import ( "fmt" "container/list" ) func main() { x :=...
      程式設計 發佈於2024-12-19
    • 大批
      大批
      方法是可以在物件上呼叫的 fns 數組是對象,因此它們在 JS 中也有方法。 slice(begin):將陣列的一部分提取到新數組中,而不改變原始數組。 let arr = ['a','b','c','d','e']; // Usecase: Extract till index ...
      程式設計 發佈於2024-12-19
    • 使用 html css 和 javascript 幻覺的 Tic-Tac-Toe 遊戲 https://www.instagram.com/webstreet_code/
      使用 html css 和 javascript 幻覺的 Tic-Tac-Toe 遊戲 https://www.instagram.com/webstreet_code/
      在 Instagram 上關注我們:https://www.instagram.com/webstreet_code/ ? ✨ 有玻璃效果的井字遊戲! ✨? 我剛剛使用 HTML、CSS 和 JavaScript 構建了一款經典的 Tic-Tac-Toe 遊戲,具有時尚的玻璃態設計。觀看視頻,看看...
      程式設計 發佈於2024-12-19
    • TB 級資料庫的 MySQL 與 NoSQL:聚集索引何時是正確的解決方案?
      TB 級資料庫的 MySQL 與 NoSQL:聚集索引何時是正確的解決方案?
      MySQL:探索資料庫設計迷宮優化大型資料庫時,必須考慮資料庫設計策略以提高效能。在給定的場景中,包含執行緒的 TB 級資料庫由於其龐大的規模而面臨效能挑戰。本文探討了 MySQL 和 NoSQL 之間的選擇,重點介紹了 MySQL 的 innodb 引擎及其聚集索引的優點。 了解 MySQL 的 ...
      程式設計 發佈於2024-12-19
    • 為什麼我的 Spring Boot 應用程式不自動建立資料庫架構?
      為什麼我的 Spring Boot 應用程式不自動建立資料庫架構?
      在 Spring Boot 中自動建立資料庫架構啟動 Spring Boot 應用程式時,可能會遇到自動建立資料庫架構的問題。以下故障排除步驟旨在解決此問題:1.實體類別包:確保實體類別位於使用@EnableAutoConfiguration註解的類別的同一個套件或子包中。否則,Spring 將不會...
      程式設計 發佈於2024-12-18
    • CSS3 轉場是否提供事件來偵測起點和終點?
      CSS3 轉場是否提供事件來偵測起點和終點?
      了解 CSS3 過渡事件CSS3 過渡允許在 Web 元素上實現流暢的動畫和視覺效果。為了增強使用者體驗並使操作與這些轉換同步,監控其進度非常重要。本文解決了 CSS3 是否提供事件來檢查過渡何時開始或結束的問題。 W3C CSS 過渡草案W3C CSS 過渡草案規定CSS 轉換會觸發對應的 DOM...
      程式設計 發佈於2024-12-18
    • Java 中可以手動釋放記憶體嗎?
      Java 中可以手動釋放記憶體嗎?
      Java 中的手動內存釋放與垃圾回收與C 不同,Java 採用託管內存框架來處理內存分配和釋放由垃圾收集器(GC) 自動執行。這種自動化方法可以提高記憶體利用率並防止困擾 C 程式的記憶體洩漏。 Java 中可以手動釋放記憶體嗎? 由於 Java 的記憶體管理是由GC,它沒有提供像 C 中的 fre...
      程式設計 發佈於2024-12-18
    • Java 1.6 中如何可靠地確定檔案是否為符號連結?
      Java 1.6 中如何可靠地確定檔案是否為符號連結?
      在 Java 1.6 中驗證符號連結確定符號連結的存在對於各種文件處理操作至關重要。在 Java 中,識別符號連結時需要考慮一些潛在問題,特別是在目錄遍歷的上下文中。 檢查符號連結的常見方法是比較文件的絕對路徑和規範路徑。規範路徑表示檔案的標準化路徑,而絕對路徑可能包括符號連結。傳統上,概念是如果這...
      程式設計 發佈於2024-12-17
    • 如何使背景顏色透明,同時保持文字不透明?
      如何使背景顏色透明,同時保持文字不透明?
      背景顏色的不透明度而不影響文本在Web 開發領域,實現透明度通常對於增強視覺吸引力和網站元素的功能。常見的要求是對 div 背景套用透明度,同時保留所包含文字的不透明度。這可能會帶來挑戰,特別是在確保跨瀏覽器相容性方面。 rgba 解決方案最有效且廣泛支持的解決方案是利用「RGBA」(紅、綠、藍、A...
      程式設計 發佈於2024-12-17
    • PHP 字串比較:`==`、`===` 或 `strcmp()` – 您應該使用哪個運算子?
      PHP 字串比較:`==`、`===` 或 `strcmp()` – 您應該使用哪個運算子?
      PHP 中的字串比較:'=='、'===' 或 'strcmp()'? PHP 中的字串比較PHP 可以使用不同的運算子來完成,例如「==」、「===」或「strcmp()」函數。此比較涉及檢查兩個字串是否相等。 '==' 與'...
      程式設計 發佈於2024-12-17

    免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

    Copyright© 2022 湘ICP备2022001581号-3