2017-04-11 51 views
0

我想确保我的Go包使用由“dal”包提供的var实例,并且不会意外地直接导入和使用db访问包。是否有可能单元测试我的软件包没有导入特定的软件包?

我想我可以做源代码的正则表达式搜索,但我想知道是否有一种方法来确保通过标准的Go测试规则?

只给一个想法是什么,我该怎么办:

接口封装:

package dal 

type UserDal interface { 
    GetUser(id int) User 
} 

实现包:

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{} 
} 

用户代码包:

import (
    "dal" 
    "some_db" <-- Fail here! 
) 

func someFunc() { 
    user := dal.User.GetUser(1) // Right way 
    some_db.DoSomething() <-- Fail here! 
} 
Slightl
+0

如果'dal'返回与其他'db'包不同的类型,则可以使用反射来检查var的类型,包括包路径。但是,如果'dal'返回'db'中定义的类型,而不是正则表达式,则可以使用'go/ast'和co。包来确定'var'在源代码中的设置方式和位置,但是我不确定它是否可以证明它的真实性......但说实话,如果你想听到某人的意见,看起来像你过度使用它,不得不做过度复杂的测试通常是一种糟糕的设计。 – mkopriva

+0

“dal”包含由相应的DAL实现分配的var变量。考虑依赖注入。 我会添加代码来提问。 –

+1

鉴于您的更新,如果您不想允许导入特定的包和使用该包,反射不会帮助您,'reflect'包无法告诉您哪些包是通过导入的调用包,也不能告诉你如何以及在哪里使用特定的包。我会选择@David Joyner的解决方案。 – mkopriva

回答

5

y比grep更可靠:使用标准parser package解析目标源并检查AST。您需要寻找ImportSpec与数据库访问包匹配的节点。如果发现任何错误,则通过测试。

+0

我在想如果可能的话反射应该更快? –

+0

@AlexanderTrakhimenok:反射需要编译和运行程序,而解析文件只需要读取源文件。你也不能反思一个“包” - 如果包未被使用,它在编译后的二进制文件中不存在。 – JimB

+0

@Jimb,但是当我运行标准Go单元测试时,它会编译包。我认为反思应该在那里工作得很好。 –