GoLang中是否存在分离单元测试和集成测试的最佳实践(作证)?我有混合的单元测试(不依赖于任何外部资源,因此运行速度非常快)和集成测试(它依赖于任何外部资源,因此运行速度较慢).因此,我希望能够控制是否包含集成测试go test
.
最直接的技术似乎是在main中定义-integrate标志:
var runIntegrationTests = flag.Bool("integration", false
, "Run the integration tests (in addition to the unit tests)")
Run Code Online (Sandbox Code Playgroud)
然后在每个集成测试的顶部添加一个if语句:
if !*runIntegrationTests {
this.T().Skip("To run this test, use: go test -integration")
}
Run Code Online (Sandbox Code Playgroud)
这是我能做的最好的吗?我搜索了testify文档,看看是否有一个命名约定或者某些内容为我完成了这个,但没有找到任何东西.我错过了什么吗?
这是我正在尝试做的事情:
main.go
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func main() {
mainRouter := mux.NewRouter().StrictSlash(true)
mainRouter.HandleFunc("/test/{mystring}", GetRequest).Name("/test/{mystring}").Methods("GET")
http.Handle("/", mainRouter)
err := http.ListenAndServe(":8080", mainRouter)
if err != nil {
fmt.Println("Something is wrong : " + err.Error())
}
}
func GetRequest(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
myString := vars["mystring"]
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte(myString))
}
Run Code Online (Sandbox Code Playgroud)
这将创建一个基于端口的基本http服务器,8080
该服务器回显路径中给出的URL参数.因此,http://localhost:8080/test/abcd
它将回写包含abcd
在响应正文中的响应.
该GetRequest()
函数的单元测试在main_test.go中:
package main
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/gorilla/context"
"github.com/stretchr/testify/assert"
)
func TestGetRequest(t *testing.T) …
Run Code Online (Sandbox Code Playgroud) 我正在使用 go lang testing 在 for 循环中运行具有多个参数的测试。
我遇到了每次调用模拟时都返回相同返回值(和第一组)的情况。我希望能够做的是在输入相同时更改每个测试的返回值,即在循环中相同On
但不同Return
。
我正在使用拉伸器/作证进行模拟。看起来它不会在相同时覆盖已经创建的模拟On
。
func TestUpdateContactWithNewActions(t *testing.T) {
tests := []struct {
testName string
getParams func() *activities.UpdateContactWithNewActionsActivity
mockError error
}{
{"UpdateContactWithNewActions with error from contact service",
func() *activities.UpdateContactWithNewActionsActivity {
return fixtures.GetUpdateContactWithNewActionsActivity()
}, fixtures.Err},
{"UpdateContactWithNewActions valid",
func() *activities.UpdateContactWithNewActionsActivity {
return fixtures.GetUpdateContactWithNewActionsActivity()
}, nil},
}
lib.LoadWithMockClients()
for _, test := range tests {
test := test
t.Run(test.testName, func(t *testing.T) {
lib.MockCSClient.On(
"UpdateContactWithNewActions",
mock.AnythingOfType("tchannel.headerCtx"),
fixtures.UpdateContactWithNewActions).Return(test.mockError)
returnedResult, err := test.getParams().Execute(fixtures.Ctx)
if test.mockError == …
Run Code Online (Sandbox Code Playgroud) 我正在使用testify进行测试。我已经为我的测试设置了一套套件。但是,在使用表测试时,我在使用设置和拆卸功能时遇到了问题。这是设计使然吗?
package workflows
import (
"testing"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/suite"
)
type UnitTestSuite struct {
suite.Suite
}
func (s *UnitTestSuite) SetupTest() {
log.Info("setup")
}
func (s *UnitTestSuite) BeforeTest(suiteName, testName string) {
log.Info("before test")
}
func (s *UnitTestSuite) AfterTest(suiteName, testName string) {
log.Info("After test")
}
func (s *UnitTestSuite) Test_TableTest() {
type testCase struct {
name string
}
testCases := []testCase{
{
name: "1",
},
{
name: "2",
},
}
for _, testCase := range testCases {
s.Run(testCase.name, func() …
Run Code Online (Sandbox Code Playgroud) 考虑 Go 中的这个单元测试文件。我正在使用github.com/stretchr/testify/mock
包。
type Person struct {Name string; Age int}
type Doer struct { mock.Mock }
func (d *Doer) doWithThing(arg Person) {
fmt.Printf("doWithThing %v\n", arg)
d.Called(arg)
}
func TestDoer(t *testing.T) {
d := new(Doer)
d.On("doWithThing", mock.Anything).Return()
d.doWithThing(Person{Name: "John", Age: 7})
// I don't care what Age was passed. Only Name
d.AssertCalled(t, "doWithThing", Person{Name: "John"})
}
Run Code Online (Sandbox Code Playgroud)
该测试失败,因为当我未超过年龄时testify
用于Age: 0
比较。我明白了,但我想知道,我该如何断言已通过的部分论点?我希望这个测试能够通过Age
,只要Name = John
文档AssertExpectations
说“AssertExpectations 断言用 On 和 Return 指定的所有内容实际上都按预期调用。调用可能以任何顺序发生。” 如果我想断言某些调用是按顺序发生的怎么办?
gomock 有*Call.After(*Call)
这个,但我在作证中看不到任何类似的东西。有没有办法,或者我应该只使用 gomock?
我在golang
.
但是现在我在运行时遇到错误go test -v
。
我想解决这个错误并使测试成功。
article
? client
? api
? ? main.go
? ? contoroller
? ? ? contoroller.go
? ? ? contoroller_test.go
? ? service
? ? ? service.go
? ? ? service_test.go
? ? dao
? ? ? dao.go
? ? ? dao_test.go
? ? s3
? ? ? s3.go
? ? ? s3_test.go
? ? go.mod
? ? go.sum
? ? Dockerfile
? nginx
? docker-compose.yml
Run Code Online (Sandbox Code Playgroud)
现在我正在service_test.go
为service.go
.
service_test.go …
下面的函数描述了如何使用 testify 进行模拟。args.Bool(0)
,args.Error(1)
是模拟的位置返回值。
func (m *MyMockedObject) DoSomething(number int) (bool, error) {
args := m.Called(number)
return args.Bool(0), args.Error(1)
}
Run Code Online (Sandbox Code Playgroud)
是否可以返回除 args.Int()
,之外的任何内容args.Bool()
?args.String()
如果我需要退货怎么办int64
,或者定制struct
。有什么方法或者我错过了什么吗?
例如:
func (m *someMock) doStuff(p *sql.DB, id int) (res int64, err error)
Run Code Online (Sandbox Code Playgroud) 所以我使用嘲笑和作证在 golang 中进行单元测试
测试代码是这样的:
const bufSize = 1024 * 1024
var lis *bufconn.Listener
var mockAccountService = &mocks.AccountService{}
func init() {
lis = bufconn.Listen(bufSize)
s := grpc.NewServer()
RegisterAccountManagementHandlerServer(s, &server{mockAccountService})
go func() {
if err := s.Serve(lis); err != nil {
log.Fatalf("Server exited with error: %v", err)
}
}()
}
func bufDialer(context.Context, string) (net.Conn, error) {
return lis.Dial()
}
func TestSayHello(t *testing.T) {
var a uint64 = 1
ctx := context.Background()
conn, err := grpc.DialContext(ctx, "bufnet", grpc.WithContextDialer(bufDialer), grpc.WithInsecure())
if …
Run Code Online (Sandbox Code Playgroud) 我正在使用testify来测试我的代码,我想检查函数是否被调用.
我正在做以下事情:
type Foo struct {
mock.Mock
}
func (m Foo) Bar() {
}
func TestFoo(t *testing.T) {
m := Foo{}
m.Bar()
m.AssertCalled(t, "Bar")
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误:
Error: Should be true
Messages: The "Bar" method should have been called with 0 argument(s), but was not.
mock.go:419: []
Run Code Online (Sandbox Code Playgroud)
我调用函数"Bar"并立即询问它是否被调用但返回false.我究竟做错了什么?测试函数是否通过testify调用的正确方法是什么?