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文件作为这两个的配置文件都行。

相关推荐
用户7438356135120 小时前
无锁 Hub:我的 IM 系统为什么用 channel 而不是 mutex 管理在线用户
go
吴佳浩2 天前
Go史上最大“打脸”现场来了:泛型方法终于实现了
后端·go
明月_清风2 天前
深入 Go 并发编程:从 Goroutine 到 Channel 的系统性避坑指南
后端·go
用户34232323763173 天前
开源!Go+Wails+Vue3 手搓一个 PLC 实时监控桌面工具
go
止语Lab3 天前
为什么你的 Go TCP server P99 延迟这么高
go
Andy Dennis3 天前
nsq学习记录
消息队列·go·nsq
韦胖漫谈IT3 天前
选语言不是站队,是选适合问题的工具
java·python·ai·rust·go·技术落地
喵个咪4 天前
GoWind Toolkit Go后端代码生成 完整全流程实战
后端·go·orm
夜悊4 天前
Go网络编程的学习代码示例:客户端/服务端(C/S)模型
go