Unit testing 是否可以对我的包进行单元测试,以确保我的包不导入特定的包?
我希望确保我的Go包使用“dal”包提供的var实例,并且不会意外地直接导入和使用db-access包 我想我可以在源代码上进行regexp搜索,但我想知道是否有办法通过标准的Go测试来确保规则 只是想告诉大家我将要做什么: 接口包:Unit testing 是否可以对我的包进行单元测试,以确保我的包不导入特定的包?,unit-testing,go,Unit Testing,Go,我希望确保我的Go包使用“dal”包提供的var实例,并且不会意外地直接导入和使用db-access包 我想我可以在源代码上进行regexp搜索,但我想知道是否有办法通过标准的Go测试来确保规则 只是想告诉大家我将要做什么: 接口包: package dal type UserDal interface { GetUser(id int) User } import ( "dal" "some_db" <-- Fail here! ) func someFunc() {
package dal
type UserDal interface {
GetUser(id int) User
}
import (
"dal"
"some_db" <-- Fail here!
)
func someFunc() {
user := dal.User.GetUser(1) // Right way
some_db.DoSomething() <-- Fail here!
}
实施方案:
package dal_db_specific
import (
"some_db"
"dal"
)
type UserDalDbSpecific struct {
}
func (_ UserDalDbSpecific) GetUser(id int) User {
some_db.executeQuery(...)
...
return user
}
register_dal() {
dal.UserDal = UserDalDbSpecific{}
}
用户代码包:
package dal
type UserDal interface {
GetUser(id int) User
}
import (
"dal"
"some_db" <-- Fail here!
)
func someFunc() {
user := dal.User.GetUser(1) // Right way
some_db.DoSomething() <-- Fail here!
}
导入(
“达尔”
“一些”比grep稍可靠:使用标准解析目标源并检查AST。您将查找与DB access包匹配的节点。如果找到任何节点,则测试失败。比grep稍可靠:使用标准解析目标源并检查AST。您将查找与DB access包匹配的节点ss包。如果发现任何包,则测试失败。如果dal
返回与其他db
包不同的类型,您可以使用反射来检查var
的类型,包括包路径。但是如果dal
返回在db
中定义的类型,则可以使用go/ast
和co.p包来确定如何以及在源代码中设置var
,但我不确定这是否是傻瓜式的……不过,老实说,如果你想听听别人的意见,似乎你做得太过分了,而且不得不做过于复杂的测试,这通常是一种糟糕设计的味道保存和接口变量,该变量由相应的DAL实现分配。考虑依赖项注入。我将向问题中添加代码。鉴于您的更新,如果您不希望导入特定的包并使用该包,反射将不会帮助您,反射包无法告诉您我们需要哪些包通过调用包重新导入,它也无法告诉您如何以及在何处使用特定包。我同意@David Joyner的解决方案。这些测试试图阻止什么行为?直接导入某些\u db
的成本是多少?您不希望人们意外连接到某些数据库吗?此测试是否如此正确解决问题?这是安全问题吗?@dm03514测试有两个目的。第一个目的是确保正确分离关注点。第二个目的是防止编译和测试速度下降-例如从“google.golang.org/appengine/datastore”导入内容可以显著增加编译时间。如果dal
返回与其他db
包不同的类型,则可以使用反射来检查var
的类型,包括包路径。但是如果dal
返回在db
中定义的类型,则可以使用go/ast
和co.pac>代替regexpkages需要确定如何以及在源代码中设置var
,但我不确定这是否是傻瓜式的……不过,老实说,如果你想听听别人的意见,似乎你做得太过火了,不得不做过于复杂的测试,这通常是一种糟糕设计的味道保存和接口变量,该变量由相应的DAL实现分配。考虑依赖项注入。我将向问题中添加代码。鉴于您的更新,如果您不希望导入特定的包并使用该包,反射将不会帮助您,反射包无法告诉您我们需要哪些包通过调用包重新导入,它也无法告诉您如何以及在何处使用特定包。我同意@David Joyner的解决方案。这些测试试图阻止什么行为?直接导入某些\u db
的成本是多少?您不希望人们意外连接到某些数据库吗?此测试是否如此正确解决问题?这是安全问题吗?@dm03514测试有两个目的。第一个目的是确保正确分离关注点。第二个目的是防止编译和测试速度下降-例如从“google.golang.org/appengine/datastore”导入内容可以显著增加编译时间。我在想,如果可能的话,反射应该更快?@AlexanderTrakhimenok:反射需要编译和运行程序,而解析文件只依赖于读取源代码。你也不能对“包”进行反射--如果未使用该包,则该包不存在于已编译的二进制文件中。@Jimb但当我运行标准Go单元测试时,它会编译该包。我认为反射应该可以在那里正常工作。@AlexanderTrakhimenok:反射可以在值上工作。如果你有一个要验证的值,你可以检查它的类型的PkgPath限定符。你不能在运行时检查导入,因为导入语句不是执行代码,它们在运行时不存在。@JimB谢谢,这就是我所怀疑的。看起来s最好的选择是使用parser AST选项。我在想,如果可能的话,反射应该更快?@AlexanderTrakhimenok:反射需要编译和运行程序,而解析文件只依赖于读取源代码。你也不能对“包”进行反射--如果未使用该包,则该包不存在于已编译的二进制文件中。@Jimb但当我运行标准Go单元测试时,它会编译该包。我认为反射应该可以在那里正常工作。@AlexanderTrakhimenok:反射可以在值上工作。如果你有一个要验证的值,你可以检查它的类型的PkgPath限定符。你不能在运行时检查导入,因为导入语句不是执行代码,它们在运行时不存在。@JimB谢谢,这就是我所怀疑的。看起来s最好的选择是使用解析器AST选项。