在Go语言中使用测试包导入循环。

huangapple go评论113阅读模式
英文:

import cycle in golang with test packages

问题

我正在尝试重构一些测试代码,在两个包中我需要做相同的事情(连接到数据库)。我遇到了一个导入循环的问题。我知道为什么不能这样做,但我想知道解决这个问题的最佳方法是什么。

具体来说,我有三个包:testutilsclientengine

engine包中,我定义了一个接口和一个实现(都是导出的)。

  1. package engine
  2. type QueryEngine interface {
  3. // ...
  4. }
  5. type MagicEngine struct {
  6. // ...
  7. }

然后在testutils包中,我将创建一个MagicEngine并尝试返回它。

  1. package testutils
  2. func CreateAndConnect() (*engine.MagicEngine, error) {
  3. // ....
  4. }

现在在测试代码中(使用TestMain),我需要做类似这样的事情:

  1. package engine
  2. func TestMain(m *testing.M) {
  3. e, err := testutils.CreateAndConnect()
  4. // ....
  5. os.Exit(m.Run())
  6. }

这当然是一个循环。我想这样做是为了在client包中也可以使用testutils.CreateAndConnect()方法。我不想在两个包中重复代码。我也不想将其放在engine包的主要代码中,因为它与测试非常相关。

我尝试将其添加为engine测试类(engine/engine_test.go)上的一个导出方法,并在client/client_test.go中使用它。但是不起作用。:/

我觉得我在其他语言中做过类似的事情,但可能记错了。如何为可重用性结构化这段代码是最佳方式?

英文:

I am trying to refactor some test code and in two packages I need to do the same thing (connect to a DB). I am getting an import cycle. I get why I can't do it, but am wondering what the best way around it is.

Some specifics, I have three packages: testutils, client, engine.

In engine I define an interface & implementation (both exported).

  1. package engine
  2. type interface QueryEngine {
  3. // ...
  4. }
  5. type struct MagicEngine {
  6. // ...
  7. }

And then in the testutils package I will create a MagicEngine and try and return it.

  1. package testutils
  2. func CreateAndConnect() (*engine.MagicEngine, error) {
  3. // ....
  4. }

Now in the test code (using a TestMain) I need to do something like

  1. package engine
  2. func TestMain(m *testing.M) {
  3. e, err := testutils.CreateAndConnect()
  4. // ....
  5. os.Exit(m.Run())
  6. }

This is of course a cycle. I want to do this so that I can in the client package also use this testutils.CreateAndConnect() method. I don't want to repeat the code in both packages. I don't want it in the main code of the engine package, it is very specific to the tests.

I tried adding it as an exported method on the engine test class (engine/engine_test.go) and using it in the client/client_test.go. No dice. :/

I feel I have done this in other languages, but could be crazy. What is the best way to structure this code for reusability?

答案1

得分: 4

你可以使用黑盒测试的方式,因为引擎的组件是被导出的。将你的测试更改为在engine_test包中:

  1. package engine_test
  2. import "engine"
  3. import "testutils"
  4. func TestMain(m *testing.M) {
  5. e, err := testutils.CreateAndConnect()
  6. // ....
  7. os.Exit(m.Run())
  8. }
英文:

You could use black-box style testing because the components of engine are exported. Change your tests to be in package engine_test:

  1. package engine_test
  2. import "engine"
  3. import "testutils"
  4. func TestMain(m *testing.M) {
  5. e, err := testutils.CreateAndConnect()
  6. // ....
  7. os.Exit(m.Run())
  8. }

huangapple
  • 本文由 发表于 2016年8月19日 06:10:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/39028261.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定