我正在用 Go 构建 REST API。godotenv 包用于加载环境变量。运行go run main.go,项目按预期运行 API,环境变量已加载。
但是,当想要使用以下命令运行测试时:go test ./...- 其中运行config/config_test.go- 它会抛出以下错误:(Error loading .env file如函数中指定的)。
鉴于以下项目结构:
> app
> auth
> config
- config.go
- config_test.go
> migrations
> static
> vendor
- .env
- .gitignore
- docker-compose.yml
- go.mod
- go.sum
- main.go
- README.md
Run Code Online (Sandbox Code Playgroud)
在config.go中,我使用以下函数来加载数据库配置。
func GetConfig() *Config {
err := godotenv.Load(".env")
if err != nil {
log.Fatalf("Error loading .env file")
}
dbHost …Run Code Online (Sandbox Code Playgroud) 我有一个具有以下结构的 Go 项目:
foo/foo.go
foo/foo_test.go
main.go
Run Code Online (Sandbox Code Playgroud)
如您所见,没有针对main.go.
我使用以下命令收集覆盖率报告:
go test ./foo ./ -coverprofile=coverage.txt -covermode=atomic
Run Code Online (Sandbox Code Playgroud)
在这里./foo并./显示在哪里寻找包裹。
问题:我将覆盖率报告发送到 codecov.io,它显示我的代码 100% 被测试覆盖。但这不是真的,因为我main.go根本没有测试。
系统似乎只计算那些明确指定测试文件的包。
问题:如何修复覆盖率报告以计算有关未测试包的信息?
注意:你可以在GitHub 上找到我的项目,真正的统计数据在这里。该项目具有不同的结构,但问题仍然存在(错误的覆盖范围)。
我对 Go 还很陌生,而且我来自 OOP 语言。现在,接口和类的概念似乎完全不同。
我想知道在测试时模拟如何工作。我遇到的困惑是是否可以用作struct类以及下面的方法是否是您想要的方法?假设这DefaultArticlesRepository将用于真实数据和MockArticlesRepository模拟它。
type ArticlesRepository interface {
GetArticleSections() []ArticleSectionResponse
}
type DefaultArticlesRepository struct{}
type MockArticlesRepository struct{}
func (repository DefaultArticlesRepository) GetArticleSections() []ArticleSectionResponse {
return []ArticleSectionResponse{
{
Title: "Default response",
Tag: "Default Tag",
},
}
}
func (repository MockArticlesRepository) GetArticleSections() []ArticleSectionResponse {
return []ArticleSectionResponse{
{
Title: "Mock response",
Tag: "Mock Tag",
},
}
}
func ArticleSectionsProvider(v ArticlesRepository) ArticlesRepository {
return v
}
func TestFoo(t *testing.T) {
realProvider := ArticleSectionsProvider(DefaultArticlesRepository{})
mockProvider := ArticleSectionsProvider(MockArticlesRepository{})
assert.Equal(t, …Run Code Online (Sandbox Code Playgroud) 我在使用通道进行测试时遇到了一个奇怪的问题。
在正常的main函数中,下面的代码会报死锁错误。
package main
import (
"fmt"
)
func main() {
c := make(chan int)
c <- 1
fmt.Println(<-c)
}
Run Code Online (Sandbox Code Playgroud)
但在我的机器上,这个简单的测试似乎陷入僵局或永远被阻止,或者由于某种我不知道的原因而无法退出。我在 Emacs 和终端中调用了测试,得到了相同的结果。命令是go test -run TestChan\$ . -v -count=1。我尝试使用更简单的命令(go test -run TestChan),但仍然得到相同的结果。我在 Go Playground(此处)上尝试过,它报告了死锁错误。我的Go环境有问题吗?
package main
import (
"fmt"
"testing"
)
func TestChan(t *testing.T) {
c := make(chan int)
c <- 1
fmt.Println(<-c)
}
Run Code Online (Sandbox Code Playgroud)
-------------------------------------------------- --------------------------------------------------
更新
看来我的问题还没有说清楚。情况是:相同的测试在我的机器和 Go Playground 上表现不同。现在我设置了-timeout 5s,但是错误信息与Go Playground上的不同。我发现与本地不同的另一件事是测试运行程序似乎与本地不同。它在包装下go-faketime。
本地输出
$ go test main_test.go -timeout 5s …Run Code Online (Sandbox Code Playgroud) 尝试通过测试容器拉取图像时出现错误 [ERROR]。原因 您组织中的 CI 计算机可以访问公共注册表服务器,但不允许与外部 Web 通信。Testcontainer java对于这个用例有类似的东西
Private registry image name
// Referring directly to an image on a private registry - image name will vary
final MySQLContainer<?> mysql = new MySQLContainer<>(
DockerImageName.parse("registry.mycompany.com/mirror/mysql:8.0.24")
.asCompatibleSubstituteFor("mysql")
)
Run Code Online (Sandbox Code Playgroud)
相当于 testcontainer-go 使用的覆盖图像注册表 url 的 go 是什么?
代码
req := testcontainers.ContainerRequest{
Image: "amazon/dynamodb-local:1.15.0",
ExposedPorts: []string{"8000" + "/tcp"},
ReaperImage: artifact_path,
}
container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
// auto-start the container
Started: true,
})
Run Code Online (Sandbox Code Playgroud)
[错误]
2021/09/28 20:21:11 Failed to pull image: Error response …Run Code Online (Sandbox Code Playgroud) 我正在模拟一个方法调用,如下所示:
tctx.someMock.On("addProd",
product.NewAddProductParamsWithContext(ctx).
WithID("someid").
WithCreateRequest(pro.CreateProdBody{
creationDate: "someDate" ,
}), nil).
Return(nil, nil)
Run Code Online (Sandbox Code Playgroud)
效果很好。
现在,在这里,creationDate如果我想概括它,使其适用于传递的任何值,而不是传递该字段的固定值,我该如何实现呢?我对 Go 还很陌生,所以不知道该怎么做
createDate 的值可以是任何值,例如 -2021-03-19T18:57:16.589Z或2022-04-23T14:17:56.589Z等。我只是不想限制模拟调用以适用于creationDate 的固定值,但我希望它适用于传递的任何日期字符串
我知道为了避免在 Go 测试中缓存结果,您可以在命令-count=1中使用该标志go test,但为什么呢?
这是来自文档:
显式禁用测试缓存的惯用方法是使用
-count=1
该标志的解释count是:
-count n
Run each test, benchmark, and fuzz seed n times (default 1).
If -cpu is set, run n times for each GOMAXPROCS value.
Examples are always run once. -count does not apply to
fuzz tests matched by -fuzz.
Run Code Online (Sandbox Code Playgroud)
它没有说明任何有关缓存的信息,默认值为 1,但默认情况下不会忽略跳过缓存测试。
我需要计算 golang 项目的代码覆盖率,其中测试源将是用 Java 语言编写的集成测试。这需要首先对 go build 进行检测,然后在服务器上运行,以便测试可以运行,并且在测试结束后我们才能知道代码覆盖率是多少?我在互联网上没有找到这方面的单一参考,所有存在的都是单元测试,可以轻松运行并用于计算覆盖率
在我的 Go 代码中,我必须多次使用 filepath.Abs(),这可能会导致我的方法返回不同的错误。
func (s *service) myFunc(path string) error {
dir := s.Component().Dir()
absDir, err := filepath.Abs(dir)
if err != nil {
return my_errors.NewFailedToGetAbsoluteComponentDir()
}
absPath, err := filepath.Abs(path)
if absPath != nil {
return my_errors.NewFailedToGetAbsPath()
}
// more code...
return nil
}
Run Code Online (Sandbox Code Playgroud)
在我的单元测试中,我想测试它,但我能想到的唯一方法是将 filepath.Abs 作为依赖项注入到我的结构中。
还有其他我没想到的办法吗?或者你认为这种测试没有必要?
我的函数名称是BenchmarkArray1什么的-12代表?
BenchmarkArray1-12 1000000000 0.826 ns/op
Run Code Online (Sandbox Code Playgroud)