kitex出现:open conf/test/conf.yaml: no such file or directory

open conf/test/conf.yaml: no such file or directory

https://github.com/cloudwego/cwgo/issues/120
https://github.com/cloudwego/cwgo/issues/29

在使用Kitex生成的代码中,单元测试时回报错,如标题所示。出现该错的原因是,biz/service单元测试方法同样需要完全的框架测试,而不是独立的单元测试,就像spring boot在进行单元测试时,需要加载整个的spring环境。

看到获取conf.yaml的源码:

go 复制代码
func initConf() {
	prefix := "conf"
	confFileRelPath := filepath.Join(prefix, filepath.Join(GetEnv(), "conf.yaml"))
	content, err := ioutil.ReadFile(confFileRelPath)
	if err != nil {
		panic(err)
	}

	conf = new(Config)
	err = yaml.Unmarshal(content, conf)
	if err != nil {
		hlog.Error("parse yaml error - %v", err)
		panic(err)
	}
	if err := validator.Validate(conf); err != nil {
		hlog.Error("validate config error - %v", err)
		panic(err)
	}

	conf.Env = GetEnv()

	pretty.Printf("%+v\n", conf)
}

调用该方法时默认会中当前目录下按照设置的位置查找配置文件,而配置文件实在根目录下,所以显然是找不到的。

此时只需要将查找conf.yaml的位置设置为绝对的路径,这样不管在那个文件下使用单元测试,配置文件的修改都是从绝对目录查询,就不会报错找不到了。

需要注意的conf.go虽然是在[project]/conf下,但是代码中确实动态变化的,也就是谁调用conf.goinitconf方法,获取的就是调用者当前的路径。

以下有三个获取路径的方法请选择合适的应用:

go 复制代码
package main

import (
	"fmt"
	"os"
	"path/filepath"
)

func main() {
	// 获取当前工作目录的绝对路径
	currentDir, err := os.Getwd()
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println("Current working directory:", currentDir)

	// 获取当前文件的绝对路径
	currentFile, err := os.Executable()
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println("Current executable file:", currentFile)

	// 获取当前项目根目录的绝对路径
	projectRoot := filepath.Dir(currentFile)
	fmt.Println("Project root directory:", projectRoot)
}

小编的想法是:

  1. 获取conf调用者的绝对路径os.Getwd()
  2. 由于go无法获取整个项目的绝对路径,那么就需要对路径解析获取项目绝对路径
  3. 使用filepathDir(currentDir)获取上一级目录
  4. 使用filepath.Base(currentDir)获取3的最后一个目录的名称,并与项目根目录比较
  5. 相等就说明该路径为绝对路径
  6. 通过1,2,3,4,5不论在任何目录调用,不论绝对地址如何变化,都可以获取项目根目录
  7. 根目录(项目名的比较可以从配置文件,或者从main函数得到,不要想我一些写死在代码中) 【可选】

那么修改后的conf的initConf代码如下:

go 复制代码
func initConf() {
	//prefix := "conf"
	//confFileRelPath := filepath.Join(prefix, filepath.Join(GetEnv(), "conf.yaml"))
	// configuration the absolute path of conf file
	currentDir ,err  := os.Getwd()
	// Go语言并知道那个是整个项目的根路径,需要人为判断
	for{
		currentDir = filepath.Dir(currentDir)
		// 该项目名可在配置文件获取
		if filepath.Base(currentDir) == "food_platform"{break}
	}
	confFileRelPath := currentDir + "/conf/test/conf.yaml"
	content, err := ioutil.ReadFile(confFileRelPath)
	if err != nil {
		panic(err)
	}

	conf = new(Config)
	err = yaml.Unmarshal(content, conf)
	if err != nil {
		hlog.Error("parse yaml error - %v", err)
		panic(err)
	}
	if err := validator.Validate(conf); err != nil {
		hlog.Error("validate config error - %v", err)
		panic(err)
	}

	conf.Env = GetEnv()

	pretty.Printf("%+v\n", conf)
}

/testfood_platform都可以从main函数中定义。甚至再创建一个yaml文件作为这两个的配置文件都行。

相关推荐
zhuyasen15 小时前
PerfTest: 压测工具界的“瑞士军刀”,原生支持HTTP/1/2/3、Websocket,同时支持实时监控
go·测试
年轻的麦子1 天前
Go 框架学习之:go.uber.org/fx项目实战
后端·go
粘豆煮包1 天前
脑抽研究生Go并发-1-基本并发原语-下-Cond、Once、Map、Pool、Context
后端·go
程序员爱钓鱼1 天前
Go语言实战案例-实现简易定时提醒程序
后端·google·go
岁忧2 天前
(LeetCode 面试经典 150 题) 200. 岛屿数量(深度优先搜索dfs || 广度优先搜索bfs)
java·c++·leetcode·面试·go·深度优先
程序员爱钓鱼2 天前
Go语言实战案例- 命令行参数解析器
后端·google·go
墩墩分墩2 天前
【Go语言入门教程】 Go语言的起源与技术特点:从诞生到现代编程利器(一)
开发语言·后端·golang·go
程序员爱钓鱼3 天前
Go语言实战案例- 开发一个ToDo命令行工具
后端·google·go
科技树支点3 天前
无GC的Java创新设计思路:作用域引用式自动内存管理
java·python·go·web·编程语言·编译器
qq_172805593 天前
GO : cannot find module
学习·go