【问题标题】:Package Import error on GolangGolang 上的包导入错误
【发布时间】:2017-12-06 13:48:21
【问题描述】:

我的帖子有 2 个问题

我基本上是想了解如何将 gomock 与 gingko 一起使用

GOPATH

/Users/Ratatouille/Desktop/test/goExample

以下项目位于

/Users/Ratatouille/Desktop/test/goExample/square

项目结构如下

.
├── area.go
└── area_test
    ├── area_mock.go
    ├── area_mock_test.go
    └── area_suite_test.go

我无法理解为什么会出现以下错误

Failed to compile area_test:

can't load package: package ./area_test: found packages area_test (area_mock.go) and area (area_mock_test.go) in /Users/Ratatouille/Desktop/test/goExample/square/area_test

Ginkgo ran 1 suite in 303.243871ms
Test Suite Failed

我的第二个问题是项目 repo 有 area.go 文件,看起来像这样

package main

import "fmt"

type Square struct {
    side float32
}

func (s *Square) Area() float32 {
    return s.side * s.side
}

func (s *Square) CalculateArea(shaper Shaper) float32 {
    shaper.Area()
}

type Shaper interface {
    Area() float32
}

func main() {
    sq1 := new(Square)
    sq1.side = 2

    var areaIntf Shaper
    areaIntf = sq1
    fmt.Println(areaIntf.Area())
}

我的问题是我如何导入 main 包内area_mock_test.go

【问题讨论】:

  • 据我所知,area_mock.go 的包名应该是 area 而不是 area_test。 area_mock_test.go 的包名应该是 area_test 而不是 area。
  • @mattn 为什么我在 Go 方面相对较新。我的理解是文件中提到的package 名称采用文件所属的包。 area_mock.go 有package 'area_test'
  • 您的工作区设置完全错误。你的 go 源代码文件位于 $GOPATH/**src** 下面。阅读golang.org/doc/code.html 并坚持下去。请看一下标准库是如何进行测试的。就是这样完成的。

标签: go


【解决方案1】:

你的项目结构不是 Go 所期望的。

area_test/ 不是area 的测试。我猜你跑了go test ./area_test。这告诉 Go ./area_test 是一个项目。它尝试编译area_mock.go 并尝试使用area_mock_test.goarea_suite_test.go 作为其测试。你得到的错误是 Go 的尴尬方式告诉你它没有期望在项目文件中找到一个名为 *_test 的包。


area.go 也是个问题。您使用package main 拥有它,然后尝试使用package area_test 进行测试。它们不匹配,Go 不会喜欢它。一个包目录包含一个包。它的测试必须使用那个包或thatpackage_test。这强制一个包目录做一件事。它要么是要导入的库,要么是要运行的程序。两者都不是。

项目目录也叫square,但包是area。有文件不匹配项目名称是可以的,一个包中有多个文件也可以,但是使用一个包而不是项目目录名称是不好的做法。


还有一个问题。 Go 期望源文件位于 $GOPATH/src 中。您可以直接在$GOPATH 中获得它们。导入语句不会找到它们。


Go 的项目结构可能需要一点时间来适应,它对如何构建项目和包有非常坚定的想法(Go 对于如何编写代码以及如何不编写代码有着非常坚定的想法)。不要与之抗争。帮自己一个忙,使用~/go 的默认GOPATH 并将您的代码放入~/go/src/

你会这样写方形库。

~/go/src/square/
|--- square.go
|--- square_test.go

square.go 可能看起来像这样。

package square

type Square struct {
    Side float32
}

func (s Square) Area() float32 {
    return s.Side * s.Side
}

请注意,Side 必须大写才能成为公共数据成员。另请注意,它是按值传递的,在 Go 中,如果您打算修改结构,则样式是仅通过指针传递。

square_test.go 可能看起来像这样。

package square_test

import(
    "testing"
    "square"
    "github.com/stvp/assert"
)

func TestArea( t *testing.T ) {
    sq := square.Square{Side: 5}

    assert.Equal( t, sq.Area(), float32(25) )
}

Go 没有任何断言。 github.com/stvp/assert 提供了基础知识并消除了很多乏味。您可以通过go get github.com/stvp/assert 获取。

请注意,在package square_test 中,这是一个只能使用square 的公共接口的黑盒测试。如果你想要一个 glassbox/internal 测试,它将使用 package square 并进入它自己的文件,如 square_internal_test.go

如果你想要一个使用 square 的程序,那将在它自己单独的包目录中。它将有一个 main.gopackage mainimport "square"

How To Write Go 更详细地解释了这一点。

【讨论】:

  • Schwern 出于开发目的,人们总是必须为包做go build。没有go build 也可以直接导入,对吗?
  • @Ratatouille: go buildgo install 是你编译代码的方式,或者如果你想要的所有东西都有一个测试夹具,你也可以运行 go test。不编译就导入代码是什么意思?
  • @Ratatouille 是的,go build 将在必要时构建任何导入的包。
猜你喜欢
  • 2017-05-02
  • 1970-01-01
  • 2016-03-10
  • 2018-02-22
  • 1970-01-01
  • 2019-12-07
  • 2014-08-22
  • 2020-02-19
  • 1970-01-01
相关资源
最近更新 更多