【go项目01_学习记录12】

news2024/9/20 8:37:48

代码组织

  • 1 代码结构
  • 2 重构与测试
    • 2.1 安装测试功能
    • 2.2 testify 的常用断言函数
  • 3 表组测试

1 代码结构

所有的代码写在一个main.go文件里面,GO编译器也是可以正常执行的。但是当代码量很庞大时,很难进行维护。

Go Web 程序的代码组织

  1. 单文件——反模式
  2. 多文件——扁平模式
  3. 目录归类——分层模式

之前main.go文件里的内容:
4. 应用初始化 —— 数据库连接初始化、路由初始化、配置加载等…
5. 路由 —— 配置 URI 与控制器的对应关系
6. 控制器 —— 处理业务逻辑的 aboutHandler、homeHandler、articlesShowHandler 等
7. 数据库操作 —— 创建表、查询等
8. 数据模型 —— Article
9. 表单验证
10. 辅助函数 —— Int64ToString、RouteName2URL
11. 中间件
12. 错误处理等

2 重构与测试

2.1 安装测试功能

安装 stretchr/testify ,这是一个知名的第三方测试包,将用到它的断言(Assertion)功能。

go get github.com/stretchr/testify

编写测试文件tests/pages_test.go
后缀名 _test 是一个特殊标识,会告知 Go 编译器和工具链这是一个测试文件。Go 编译器在编译时会跳过这些文件,而工具 go test 在执行时默认会运行当前目录下所有拥有 _test 后缀名的文件。

package tests

import (
    "net/http"
    "testing"

    "github.com/stretchr/testify/assert"
)

func TestHomePage(t *testing.T) {
    baseURL := "http://localhost:3000"

    // 1. 请求 —— 模拟用户访问浏览器
    var (
        resp *http.Response
        err  error
    )
    resp, err = http.Get(baseURL + "/")

    // 2. 检测 —— 是否无错误且 200
    assert.NoError(t, err, "有错误发生,err 不为空")
    assert.Equal(t, 200, resp.StatusCode, "应返回状态码 200")
}

2.2 testify 的常用断言函数

 // 相等
func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool
func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool
// 是否为 nil
func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool
func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool
// 是否为空
func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool
func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool
// 是否存在错误
func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool
func Error(t TestingT, err error, msgAndArgs ...interface{}) bool
// 是否为 0 值
func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool
func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool
// 是否为布尔值
func True(t TestingT, value bool, msgAndArgs ...interface{}) bool
func False(t TestingT, value bool, msgAndArgs ...interface{}) bool
// 断言长度一致
func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool
// 断言包含、子集、非子集
func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool
func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool)
func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool)
// 断言文件和目录存在
func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool
func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool

在这里插入图片描述
显示ok则成功

3 表组测试

Go 语言中,对于具备相同的测试逻辑的场景,可以使用简洁紧凑的 表组测试。
tests/pages_test.go

package tests

import (
	"net/http"
	"strconv"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestAllPages(t *testing.T){

	baseURL := "http://localhost:3000"

	// 1. 声明加初始化测试数据
	var tests = []struct {
		method string
		url		string
		expected int
	}{
		{"GET","/",200},
		{"GET","/notfound",404},
		{"GET","/about",200},
		{"GET","/articles",200},
		{"POST","/articles",200},
		{"GET","/articles/create",200},
		{"GET","/articles/3",200},
		{"POST","/articles/3",200},
		{"GET","/articles/3/edit",200},
		{"POST","/articles/4/delete",404},
	}

	// 2. 遍历所有测试
	for _, test := range tests {
		t.Logf("当前请求 URL :%v \n", test.url)
		var(
			resp * http.Response
			err error
		)
		// 2.1 请求以获取响应
		switch{
		case test.method == "POST":
			data := make(map[string][]string)
			resp,err = http.PostForm(baseURL + test.url, data)
		default:
			resp,err = http.Get(baseURL + test.url)
		}
		// 2.2 断言
		assert.NoError(t,err,"请求"+test.url+" 时报错")
		assert.Equal(t, test.expected, resp.StatusCode, test.url+" 应返回状态码"+strconv.Itoa(test.expected))
	}
}

标准库里的辅助方法打印出来的数据:

t.Logf("当前请求 URL: %v \n", test.url)

在这里插入图片描述
使用 go test ./tests或者点击函数旁边的运行,前者不会显示t.Logf()里的内容,前者需要添加**-v** 详细打印。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1679456.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

滑动窗口算法及相关习题

滑动窗口 又叫"同向双指针", left和right指针构成一个窗口 一般可以利用单调性时, 用到滑动窗口 使用: 定义left 0,right 0进窗口判断出窗口 还有一步是更新结果, 在哪一步更新是根据题意的 其中234步循环进行 一. 长度最小的子数组 答案 二.无重复字符的最长…

前馈神经网络FNN、多层感知机MLP和反向传播推导

目录 一、前馈神经网络FNN 激活函数的使用 二、多层感知机MLP MLP的典型结构 多层感知机MLP的特点 和前馈神经网络FNN的区别 三、传播推导 1、前向传播(Forward propagation) (1)输入层到隐藏层 (2)隐藏层到输出层 2、…

(C语言)队列实现与用队列实现栈

目录 1.队列 1.1队列的概念及结构 1.2 队列的实际应用联想 1.3队列的实现 2. 队列应用——队列实现栈 主要思路 1.队列 1.1队列的概念及结构 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进…

报错:(idea端口被占用)Web server failed to start. Port 9090 was already in use.

cmd里面输入: netstat -ano|findstr "9090" 可以看到pid是9644 然后再打开任务管理器

Redis实战—验证码登录注册

目录 基于Session Controller层 Service层 ServiceImpl层 ​编辑校验登录状态 ThreadLocal 登录拦截器 添加拦截器到Config Controller层实现 基于Redis ServiceImpl 新增刷新拦截器 添加拦截器到Config 基于Session Controller层 /*** 发送手机验证码*/PostMappi…

Docker三剑客从0到1

一、docker三剑客介绍 使用"三剑客"可以帮助我们解决docker host维护,多容器编排部署,多个docker host集群的各个难题。 docker-machine 创建虚拟机 我们知道docker使用了linux的内核技术(namespace 资源隔离,cgroup资源限制等),那么如果我想在windows或Mac系统上…

浅析扩散模型与图像生成【应用篇】(二十五)——Plug-and-Play

25. Plug-and-Play: Diffusion Features for Text-Driven Image-to-Image Translation 该文提出一种文本驱动的图像转换方法,输入一张图像和一个目标文本描述,按照文本描述对输入图像进行转换,得到目标图像。图像转换任务其实本质上属于图像编…

【Flask框架】

6.Flask轻量型框架 6.1Flask简介 python提供的框架中已经写好了一个内置的服务器,服务器中的回应response行和头已经写好,我们只需要自己写显示在客户端,的主体body部分。 ---------------------------------------------------------- Fla…

【Linux】常用指令、热键与权限管理

一、常用指令 (1)ls 功能:列出指定目录下的所有子目录与文件 用法:ls (选项) (目录或文件名) 常用选项: -a:列出目录下的所有文件,包括隐藏…

k8s环境部署的集成arthas-spring-boot-starter spingboot项目无法访问控制台

前言 k8s环境部署的集成arthas-spring-boot-starter项目无法访问控制台,springboot项目集成arthas-spring-boot-starter 会自带个控制台 供我们访问 但是当使用k8s环境部署后 这个页面就无法访问了 分析 首先看下arthas对应的配置 arthas-spring-boot-starter 中…

linux基础指令讲解(ls、pwd、cd、touch、mkdir)

🪐🪐🪐欢迎来到程序员餐厅💫💫💫 主厨:邪王真眼 主厨的主页:Chef‘s blog 所属专栏:c大冒险 总有光环在陨落,总有新星在闪烁 这个是我们今天要用到的初始…

超实用的excel进销存管理系统(75份),自带库存预警,直接用!

进销存(Inventory Management)是企业管理中的一个核心组成部分,它涉及到商品的采购(进货)、销售和存储(库存)等环节。有效的进销存管理可以帮助企业降低成本、提高效率和客户满意度。 1. 采购管…

【上海大学计算机组成原理实验报告】五、机器语言程序实验

一、实验目的 理解计算机执行程序的实际过程。 学习编制机器语言简单程序的方法。 二、实验原理 根据实验指导书的相关内容,指令的形式化表示是指采用一种规范化的符号系统,以更清晰、精确地描述和表示指令的逻辑功能和操作步骤。 汇编是一种编程语言…

C++ 中重写重载和隐藏的区别

重写(override)、重载(overload)和隐藏(overwrite)在C中是3个完全不同的概念。我们这里对其进行详细的说明 1、重写(override)是指派生类覆盖了基类的虚函数,这里的覆盖必…

gitlab webhook触发jenkins任务

配置jenkins 安装gitlab插件 配置jenkins job 选择gitlab webhook触发 在高级中生成token 代码仓设置 新增webhook 配置webhook 测试连接 缺点,不能带gitLab事件的参数!!!

Xilinx RAM IP核的使用及注意事项

对于RAM IP核(Block Memory Generator核)的使用以及界面的配置介绍,文章RAM的使用介绍进行了较详细的说明,本文对RAM IP核使用中一些注意的地方加以说明。 文章目录 三种RAM的区别单端口RAM(Single-port RAM)简单双端口RAM(Simple Dual-port RAM)真双端…

Spring Security入门教程:实现自定义用户配置

在上一篇文章中:Spring Security入门教程:利用Spring Security实现安全控制 我们学会了使用Spring Security实现安全控制,学会了他的基础使用,这节课我们来学习一下它的自定义的功能,更深入的了解和使用Spring Securit…

计算机组成结构—寻址方法

目录 一、指令寻址 二、数据寻址 1.立即寻址 2.直接寻址 3.间接寻址 4.隐含寻址 5.寄存器寻址 6.寄存器间接寻址 7.基址寻址 8.变址寻址 9.相对寻址 10. 堆栈寻址 寻址方式是寻找指令或操作数有效地址的方式,也就是指确定本条指令的数据地址,…

C++错题集(持续更新ing)

Day 1 一、选择题 解析: 在数字不会溢出的前提下,对于正数和负数,有: 1)左移n位,相当于操作数乘以2的n次方; 2)右移n位,相当于操作数除以2的n次方。 解析&#xff1a…