英文:
Package Import error on Golang
问题
我的回答如下:
我的帖子有两个问题。
我主要想了解如何在gingko中使用gomock。
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
我的第二个问题是项目仓库中有一个名为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())
}
我的问题是如何在area_mock_test.go
中导入main
包。
英文:
My post has 2 question
I'm essentially trying to understand how to use gomock with gingko
GOPATH
/Users/Ratatouille/Desktop/test/goExample
The following project is located at
/Users/Ratatouille/Desktop/test/goExample/square
which has following project structure
.
├── area.go
└── area_test
├── area_mock.go
├── area_mock_test.go
└── area_suite_test.go
what I'm not able to understand why I'm getting following error
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
my second question is project repo has area.go file which look like this
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())
}
My question is how do I import main
package inside area_mock_test.go
答案1
得分: 2
你的项目结构不符合Go的要求。
area_test/
不是area
的测试。我猜你运行了go test ./area_test
。这告诉Go ./area_test
是一个项目。它试图编译area_mock.go
,并尝试使用area_mock_test.go
和area_suite_test.go
作为它的测试。你得到的错误是Go告诉你它不希望在项目文件中找到名为*_test
的包的奇怪方式。
area.go
也有问题。你将其使用package main
,但是尝试使用package area_test
进行测试。它们不匹配,Go不会喜欢。一个包目录包含一个包。它的测试必须使用该包或thatpackage_test
。这强制要求一个包目录只做一件事。它要么是一个要导入的库,要么是一个要运行的程序。不能两者兼而有之。
此外,项目目录被称为square
,但包名是area
。文件名与项目名不匹配是可以的,一个包中可以有多个文件,但是使用与项目目录名不同的包名不是好的做法。
还有一个问题。Go希望源文件在$GOPATH/src
中。你直接将它们放在$GOPATH
中是不行的。导入语句找不到它们。
Go的项目结构可能需要一些时间来适应,它对项目和包的结构有非常明确的想法(Go对代码的编写方式和不编写方式有非常明确的想法)。不要与之对抗。为自己做个好事,使用默认的GOPATH
,即~/go
,并将代码放在~/go/src/
中。
你可以这样编写square
库。
~/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
的公共接口的黑盒测试。如果你想要一个白盒/内部测试,它将使用package square
,并在自己的文件中,如square_internal_test.go
。
如果你想要一个使用square的程序,那将是一个独立的包目录。它将有一个main.go
,其中包含package main
和import "square"
。
如何编写Go代码对此进行了更详细的解释。
英文:
Your project structure isn't the one Go expects.
area_test/
are not the tests for area
. I'm going to guess you ran go test ./area_test
. That tells Go that ./area_test
is a project. It tried to compile area_mock.go
and tried to use area_mock_test.go
and area_suite_test.go
as its tests. The error you got is Go's awkward way of telling you that it did not expect to find a package named *_test
in a project file.
area.go
is also a problem. You have it using package main
, but then try to test with package area_test
. They don't match and Go won't like it. A package directory contains one package. Its tests must use either that package or thatpackage_test
. This enforces that a package directory does one thing. Its either a library to import, or its a program to run. Not both.
Also the project directory is called square
, but the package is area
. It's ok to have files that don't match the project name, and its fine to have multiple files in one package, but using a package than the project directory name is not good practice.
There's another problem. Go expects source files to be in $GOPATH/src
. You have them directly in $GOPATH
. Import statements won't find them.
Go's project structure can take a bit of getting used to, and it has very firm ideas about how projects and packages are to be structured (Go has very firm ideas about how code is to be written, and how it isn't). Don't fight it. Do yourself a favor and use the default GOPATH
of ~/go
and put your code in ~/go/src/
.
You'd write the square library like so.
~/go/src/square/
|--- square.go
|--- square_test.go
square.go might look like this.
package square
type Square struct {
Side float32
}
func (s Square) Area() float32 {
return s.Side * s.Side
}
Note that Side
must be capitalized for it to be a public data member. Also note that its passed by value, in Go the style is to only pass by pointer if you intend to modify the struct.
square_test.go might look like this.
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 does not come with any asserts. github.com/stvp/assert
provides the basics and removes a lot of tedium. You can get it with go get github.com/stvp/assert
.
Note that it is in package square_test
to make this a blackbox test which can only use the public interface of square
. If you wanted a glassbox/internal test, it would use package square
and go in its own file like square_internal_test.go
.
If you want a program that uses square, that would be in its own separate package directory. It would have a main.go
with package main
and import "square"
.
How To Write Go explains this in more detail.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论