Unit testing 是否可以对我的包进行单元测试,以确保我的包不导入特定的包?

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() {

我希望确保我的Go包使用“dal”包提供的var实例,并且不会意外地直接导入和使用db-access包

我想我可以在源代码上进行regexp搜索,但我想知道是否有办法通过标准的Go测试来确保规则

只是想告诉大家我将要做什么:

接口包:

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选项。