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

相关推荐
蒙娜丽宁2 天前
Go语言错误处理详解
ios·golang·go·xcode·go1.19
qq_172805592 天前
GO Govaluate
开发语言·后端·golang·go
littleschemer3 天前
Go缓存系统
缓存·go·cache·bigcache
程序者王大川4 天前
【GO开发】MacOS上搭建GO的基础环境-Hello World
开发语言·后端·macos·golang·go
Grassto4 天前
Gitlab 中几种不同的认证机制(Access Tokens,SSH Keys,Deploy Tokens,Deploy Keys)
go·ssh·gitlab·ci
高兴的才哥5 天前
kubevpn 教程
kubernetes·go·开发工具·telepresence·bridge to k8s
少林码僧5 天前
sqlx1.3.4版本的问题
go
蒙娜丽宁6 天前
Go语言结构体和元组全面解析
开发语言·后端·golang·go
蒙娜丽宁6 天前
深入解析Go语言的类型方法、接口与反射
java·开发语言·golang·go
三里清风_6 天前
Docker概述
运维·docker·容器·go