Giter Site home page Giter Site logo

stretchr / testify Goto Github PK

View Code? Open in Web Editor NEW
22.0K 174.0 1.5K 1.54 MB

A toolkit with common assertions and mocks that plays nicely with the standard library

License: MIT License

Go 99.80% Shell 0.20%
testify go assertions mocking golang testing toolkit

testify's Introduction

Testify - Thou Shalt Write Tests

ℹ️ We are working on testify v2 and would love to hear what you'd like to see in it, have your say here: https://cutt.ly/testify

Build Status Go Report Card PkgGoDev

Go code (golang) set of packages that provide many tools for testifying that your code will behave as you intend.

Features include:

Get started:

assert package

The assert package provides some helpful methods that allow you to write better test code in Go.

  • Prints friendly, easy to read failure descriptions
  • Allows for very readable code
  • Optionally annotate each assertion with a message

See it in action:

package yours

import (
  "testing"
  "github.com/stretchr/testify/assert"
)

func TestSomething(t *testing.T) {

  // assert equality
  assert.Equal(t, 123, 123, "they should be equal")

  // assert inequality
  assert.NotEqual(t, 123, 456, "they should not be equal")

  // assert for nil (good for errors)
  assert.Nil(t, object)

  // assert for not nil (good when you expect something)
  if assert.NotNil(t, object) {

    // now we know that object isn't nil, we are safe to make
    // further assertions without causing any errors
    assert.Equal(t, "Something", object.Value)

  }

}
  • Every assert func takes the testing.T object as the first argument. This is how it writes the errors out through the normal go test capabilities.
  • Every assert func returns a bool indicating whether the assertion was successful or not, this is useful for if you want to go on making further assertions under certain conditions.

if you assert many times, use the below:

package yours

import (
  "testing"
  "github.com/stretchr/testify/assert"
)

func TestSomething(t *testing.T) {
  assert := assert.New(t)

  // assert equality
  assert.Equal(123, 123, "they should be equal")

  // assert inequality
  assert.NotEqual(123, 456, "they should not be equal")

  // assert for nil (good for errors)
  assert.Nil(object)

  // assert for not nil (good when you expect something)
  if assert.NotNil(object) {

    // now we know that object isn't nil, we are safe to make
    // further assertions without causing any errors
    assert.Equal("Something", object.Value)
  }
}

require package

The require package provides same global functions as the assert package, but instead of returning a boolean result they terminate current test. These functions must be called from the goroutine running the test or benchmark function, not from other goroutines created during the test. Otherwise race conditions may occur.

See t.FailNow for details.

mock package

The mock package provides a mechanism for easily writing mock objects that can be used in place of real objects when writing test code.

An example test function that tests a piece of code that relies on an external object testObj, can set up expectations (testify) and assert that they indeed happened:

package yours

import (
  "testing"
  "github.com/stretchr/testify/mock"
)

/*
  Test objects
*/

// MyMockedObject is a mocked object that implements an interface
// that describes an object that the code I am testing relies on.
type MyMockedObject struct{
  mock.Mock
}

// DoSomething is a method on MyMockedObject that implements some interface
// and just records the activity, and returns what the Mock object tells it to.
//
// In the real object, this method would do something useful, but since this
// is a mocked object - we're just going to stub it out.
//
// NOTE: This method is not being tested here, code that uses this object is.
func (m *MyMockedObject) DoSomething(number int) (bool, error) {

  args := m.Called(number)
  return args.Bool(0), args.Error(1)

}

/*
  Actual test functions
*/

// TestSomething is an example of how to use our test object to
// make assertions about some target code we are testing.
func TestSomething(t *testing.T) {

  // create an instance of our test object
  testObj := new(MyMockedObject)

  // set up expectations
  testObj.On("DoSomething", 123).Return(true, nil)

  // call the code we are testing
  targetFuncThatDoesSomethingWithObj(testObj)

  // assert that the expectations were met
  testObj.AssertExpectations(t)


}

// TestSomethingWithPlaceholder is a second example of how to use our test object to
// make assertions about some target code we are testing.
// This time using a placeholder. Placeholders might be used when the
// data being passed in is normally dynamically generated and cannot be
// predicted beforehand (eg. containing hashes that are time sensitive)
func TestSomethingWithPlaceholder(t *testing.T) {

  // create an instance of our test object
  testObj := new(MyMockedObject)

  // set up expectations with a placeholder in the argument list
  testObj.On("DoSomething", mock.Anything).Return(true, nil)

  // call the code we are testing
  targetFuncThatDoesSomethingWithObj(testObj)

  // assert that the expectations were met
  testObj.AssertExpectations(t)


}

// TestSomethingElse2 is a third example that shows how you can use
// the Unset method to cleanup handlers and then add new ones.
func TestSomethingElse2(t *testing.T) {

  // create an instance of our test object
  testObj := new(MyMockedObject)

  // set up expectations with a placeholder in the argument list
  mockCall := testObj.On("DoSomething", mock.Anything).Return(true, nil)

  // call the code we are testing
  targetFuncThatDoesSomethingWithObj(testObj)

  // assert that the expectations were met
  testObj.AssertExpectations(t)

  // remove the handler now so we can add another one that takes precedence
  mockCall.Unset()

  // return false now instead of true
  testObj.On("DoSomething", mock.Anything).Return(false, nil)

  testObj.AssertExpectations(t)
}

For more information on how to write mock code, check out the API documentation for the mock package.

You can use the mockery tool to autogenerate the mock code against an interface as well, making using mocks much quicker.

suite package

The suite package provides functionality that you might be used to from more common object-oriented languages. With it, you can build a testing suite as a struct, build setup/teardown methods and testing methods on your struct, and run them with 'go test' as per normal.

An example suite is shown below:

// Basic imports
import (
    "testing"
    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/suite"
)

// Define the suite, and absorb the built-in basic suite
// functionality from testify - including a T() method which
// returns the current testing context
type ExampleTestSuite struct {
    suite.Suite
    VariableThatShouldStartAtFive int
}

// Make sure that VariableThatShouldStartAtFive is set to five
// before each test
func (suite *ExampleTestSuite) SetupTest() {
    suite.VariableThatShouldStartAtFive = 5
}

// All methods that begin with "Test" are run as tests within a
// suite.
func (suite *ExampleTestSuite) TestExample() {
    assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
}

// In order for 'go test' to run this suite, we need to create
// a normal test function and pass our suite to suite.Run
func TestExampleTestSuite(t *testing.T) {
    suite.Run(t, new(ExampleTestSuite))
}

For a more complete example, using all of the functionality provided by the suite package, look at our example testing suite

For more information on writing suites, check out the API documentation for the suite package.

Suite object has assertion methods:

// Basic imports
import (
    "testing"
    "github.com/stretchr/testify/suite"
)

// Define the suite, and absorb the built-in basic suite
// functionality from testify - including assertion methods.
type ExampleTestSuite struct {
    suite.Suite
    VariableThatShouldStartAtFive int
}

// Make sure that VariableThatShouldStartAtFive is set to five
// before each test
func (suite *ExampleTestSuite) SetupTest() {
    suite.VariableThatShouldStartAtFive = 5
}

// All methods that begin with "Test" are run as tests within a
// suite.
func (suite *ExampleTestSuite) TestExample() {
    suite.Equal(suite.VariableThatShouldStartAtFive, 5)
}

// In order for 'go test' to run this suite, we need to create
// a normal test function and pass our suite to suite.Run
func TestExampleTestSuite(t *testing.T) {
    suite.Run(t, new(ExampleTestSuite))
}

Installation

To install Testify, use go get:

go get github.com/stretchr/testify

This will then make the following packages available to you:

github.com/stretchr/testify/assert
github.com/stretchr/testify/require
github.com/stretchr/testify/mock
github.com/stretchr/testify/suite
github.com/stretchr/testify/http (deprecated)

Import the testify/assert package into your code using this template:

package yours

import (
  "testing"
  "github.com/stretchr/testify/assert"
)

func TestSomething(t *testing.T) {

  assert.True(t, true, "True is true!")

}

Staying up to date

To update Testify to the latest version, use go get -u github.com/stretchr/testify.


Supported go versions

We currently support the most recent major Go versions from 1.19 onward.


Contributing

Please feel free to submit issues, fork the repository and send pull requests!

When submitting an issue, we ask that you please include a complete test function that demonstrates the issue. Extra credit for those using Testify to write the test code that demonstrates it.

Code generation is used. Look for Code generated with at the top of some files. Run go generate ./... to update generated files.

We also chat on the Gophers Slack group in the #testify and #testify-dev channels.


License

This project is licensed under the terms of the MIT license.

testify's People

Contributors

adriley avatar alexandear avatar alexpantyukhin avatar arjunmahishi avatar boyan-soubachov avatar brackendawson avatar daddye avatar dependabot[bot] avatar dolmen avatar emou avatar ernesto-jimenez avatar esdrasbeleza avatar gohargasparyan avatar haraldnordgren avatar leighmcculloch avatar linusbarth avatar matryer avatar moviestoreguy avatar muesli avatar mvdkleijn avatar mvrahden avatar nelsam avatar ogoyukin avatar paulbellamy avatar posener avatar saluev avatar torkelrogstad avatar tylerb avatar viblo avatar vkryukov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

testify's Issues

Data race on mock.Called()

Parallel calls to mock.Called() cause the Go Race Detector to flag a Data Race.

Using the example from this package:

func (m *MyMockedObject) DoSomething(number int) (bool, error) {
  args := m.Mock.Called(number)
  return args.Bool(0), args.Error(1)
}

If m.DoSomething(i) is called from different threads simultaneously, this triggers a race condition in mock.Called().

To reproduce the error, please run:

go test -v github.com/buddyfs/buddystore -race -run TestIncSync

Error shown:

=== RUN TestIncSync-8
==================
WARNING: DATA RACE
Read by goroutine 9:
  github.com/stretchr/testify/mock.(*Mock).Called()
      /home/anup/gopath/src/github.com/stretchr/testify/mock/mock.go:218 +0x85f
  github.com/buddyfs/buddystore.(*MockTransport).Set()
      /home/anup/gopath/src/github.com/buddyfs/buddystore/transport_mock.go:76 +0x193
  github.com/buddyfs/buddystore.(*KVStore).incSyncToSucc()
      /home/anup/gopath/src/github.com/buddyfs/buddystore/obj_server_repl.go:234 +0x16b

Previous write by goroutine 8:
  github.com/stretchr/testify/mock.(*Mock).Called()
      /home/anup/gopath/src/github.com/stretchr/testify/mock/mock.go:218 +0x956
  github.com/buddyfs/buddystore.(*MockTransport).Set()
      /home/anup/gopath/src/github.com/buddyfs/buddystore/transport_mock.go:76 +0x193
  github.com/buddyfs/buddystore.(*KVStore).incSyncToSucc()
      /home/anup/gopath/src/github.com/buddyfs/buddystore/obj_server_repl.go:234 +0x16b

...

I'm not sure if the mock instance itself is supposed to serialize these calls (adds complexity to the mock and doesn't work across mocks).

I'm more than happy to work on this and send a pull request if this is considered to be a valid issue.

Kernel panic when calling Assert.NotEqual on byte arrays

After commit faedd6e, I get a kernel panic when calling Assert.NotEqual on two byte arrays. Before that commit, this works just fine. For example, if I do:

actualText := []byte("Hello world")
expectedText := []byte("Hello world 2")
assert.NotEqual(t, actualText, expectedText)
log.Printf("Got here")

I see a kernel panic on the assert line and "Got here" is never printed. Here's my full stack:

panic: runtime error: comparing uncomparable type []uint8 [recovered]
    panic: runtime error: comparing uncomparable type []uint8

goroutine 20 [running]:
runtime.panic(0x2a99a0, 0xc2080009b0)
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/runtime/panic.c:279 +0xf5
testing.func·006()
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/testing/testing.go:416 +0x176
runtime.panic(0x2a99a0, 0xc2080009b0)
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/runtime/panic.c:248 +0x18d
github.com/stretchr/testify/assert.ObjectsAreEqual(0x22ad80, 0xc2080430e0, 0x22ad80, 0xc208043100, 0x18)
    /Users/cary/usermind/src/github.com/stretchr/testify/assert/assertions.go:43 +0x27d
github.com/stretchr/testify/assert.NotEqual(0x541998, 0xc208046000, 0x22ad80, 0xc2080430e0, 0x22ad80, 0xc208043100, 0x0, 0x0, 0x0, 0x1)
    /Users/cary/usermind/src/github.com/stretchr/testify/assert/assertions.go:429 +0x4a
github.com/usermindinc/unity/crypto.TestOnBytes(0xc208046000)
    /Users/cary/usermind/src/github.com/usermindinc/unity/crypto/encryption_service_test.go:65 +0xc6b
testing.tRunner(0xc208046000, 0x48d7a0)
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/testing/testing.go:422 +0x8b
created by testing.RunTests
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/testing/testing.go:504 +0x8db

goroutine 16 [chan receive]:
testing.RunTests(0x38aa58, 0x48d7a0, 0x4, 0x4, 0x1)
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/testing/testing.go:505 +0x923
testing.Main(0x38aa58, 0x48d7a0, 0x4, 0x4, 0x498840, 0x0, 0x0, 0x498840, 0x0, 0x0)
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/testing/testing.go:435 +0x84
main.main()
    github.com/usermindinc/unity/crypto/_test/_testmain.go:53 +0x9c

goroutine 19 [finalizer wait]:
runtime.park(0x148c0, 0x493880, 0x492349)
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/runtime/proc.c:1369 +0x89
runtime.parkunlock(0x493880, 0x492349)
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/runtime/proc.c:1385 +0x3b
runfinq()
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/runtime/mgc0.c:2644 +0xcf
runtime.goexit()
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/runtime/proc.c:1445
exit status 2

Adding new asserts to testify/assert

Hello,

I found myself needing more advanced tests than those currently provided by testify/assert and would like to get @matryer and @tylerb (and others!) opinions on whether this is something worth including into the base package or not. I completely understand if you would want to keep it simple as it is.

Below are some proposals - I will appreciate your quick comments, and I can send pull requests for those you like:

  • Regular expression matches.
// (Not)Match asserts that a specified regexp (does not match) matches a string.
// 
//  assert.Match(t, regexp.MustCompile("start"), "it's starting")
//  assert.NotMatch(t, "^start", "it's not starting")
//
// Returns whether the assertion was successful (true) or not (false).
func Match(t TestingT, rx interface{}, str interface{}) bool
func NotMatch(t TestingT, rx interface{}, str interface{}) bool

Helpers that will use httptest internally to do the heavy lifting:

  • HTTP handler returns a success/error/redirect.
// HTTP(Success|Error|Redirect) asserts that a specified handler returns a 
// (success|failure|redirect) status code.
//
//  assert.HTTPSuccess(t, myHandler, "http://www.google.com", nil)
//  assert.HTTPError(t, myHandler, "/a/b/c", url.Values{"a": []string{"b", "c"}}
//
// Returns whether the assertion was successful (true) or not (false).
func HTTPSuccess(t TestingT, handler http.Handler, url string, values url.Values) bool
func HTTPError(t TestingT, handler http.Handler, url string, values url.Values) bool
func HTTPRedirect(t TestingT, handler http.Handler, url string, values url.Values) bool
  • HTTP handler renders an expected result.
// HTTPBody(Equal|Match|NotMatch) asserts that a specified handler returns a 
// body that (is equal to a string|matches a regular expression|does not 
// match a regular expression).
//
//  assert.HTTPBodyMatch(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
//
// Returns whether the assertion was successful (true) or not (false).
func HTTPBodyEqual(t Testing T, handler http.Handler, url string, values url.Values, body interface{}) bool
func HTTPBodyMatch(t Testing T, handler http.Handler, url string, values url.Values, body interface{}) bool
func HTTPBodyNotMatch(t Testing T, handler http.Handler, url string, values url.Values, body interface{}) bool

Mock report "Unexpected Method Call",but the arguments on two method are binary equal.

Sorry,to ask question like this.I have taken half an hour to figure out what the problem is,but failed to identify it,may be I misunderstand something,

I got an error like blow,and I checked arguments of two method calls,no difference.I assumed if arguments are identical,testify mock should work,am I right?

mock: Unexpected Method Call

ToCache(string,*initdata.InitDataForVisitor)
0: user/00001-friendGroup/001
1: &{{} {{false 0 0 false} 0 user/00001} user/00001-friendGroup/001 [] [{ friend/0001}] [] [] []}

The closest call I have is:

ToCache(string,*initdata.InitDataForVisitor)
0: user/00001-friendGroup/001
1: &{{} {{false 0 0 false} 0 user/00001} user/00001-friendGroup/001 [] [{ friend/0001}] [] [] []}
[recovered]
panic:

test case level setup/teardown

hi
i'm background of xUnit with other programming language like Java, Ruby, Python. when i fist time wrote a test case with golang, i was suprised that there is no assert (not testify works pretty well) and no fixture (setup/tearDown).
i saw testify has test suite level setup.tearDown, but i'd like to see test case level fixture support, thanks:)

Why the file "mock_test.go" is special to in getting the caller info?

Hi,

I got a little confused when browsing the code in assert/assertions.go, function CallerInfo(), line 78:

 64 func CallerInfo() string {
 65
 66         file := ""
 67         line := 0
 68         ok := false
 69
 70         for i := 0; ; i++ {
 71                 _, file, line, ok = runtime.Caller(i)
 72                 if !ok {
 73                         return ""
 74                 }
 75                 parts := strings.Split(file, "/")
 76                 dir := parts[len(parts)-2]
 77                 file = parts[len(parts)-1]
 78                 if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" {
 79                         break
 80                 }
 81         }
 82
 83         return fmt.Sprintf("%s:%d", file, line)
 84 }

Why file == "mock_test.go" would be so special as a condition to break?

mock: Add "Did you mean" option to unexpected call panic

Instead of this:

assert: mock: I don't know what to return because the method call was unexpected
Either do Mock.On("CreateResource").Return(...) first, or remove the CreateResource() call.
This method was unexpected:
CreateResource(_context.Context,_resources.Resource)
0: &{ 0xf84008b000 0xf8400015f0 0xf840066940 0xf840062480 map[]}
1: &{something map[]}
at: [ mock.go:131 ] -

Why don't we check the expected calls array (using Diff for each one) to decide the closest option of what the user could mean.

Whichever has the fewest number of differences (multiple ones is OK if there are some) should be shown as "Did you mean". We can include the argument diffs to show why it didn't match.

E.g. I am calling CreateResource and getting an error, even though I am convinced that I am calling the method that is expected and it is very difficult to debug why this is not the case.

Multilines don't play nicely with vim-go

I also opened the issue over there, but figured I'd additionally post here.

fatih/vim-go#168

I attached two screenshots. One shows how go test renders in a terminal, and the other when using :GoTest within vim. I'm using testify mostly for assert functionality.

I chatted with fatih a bit in #go-nuts, and it was said that vim-go has pretty basic support for multilines.

screenshot 2014-09-09 19 46 45
screenshot 2014-09-09 19 47 40

Add assert.Has

assert.Has should be able to tell you if a map 'has' a value for the specified key or not.

assert.Has(t, map, "Key")

Perhaps this becomes an alternative for 'assert.Contains'

Is it possible to implement partial mocking?

I think it may be impossible,but I am want to share my thought,for example

func (s *impl) test() {
if needToPartialMocked() {
doSomething()
}else{
//.......if I want to come here,I must mock dependency0 and dependency1
doElse()
}
}

func (s *impl) needToPartialMocked() bool{
if xxxx() {
return s.dependency0,IsExisted();
}else{
return s.dependency1.IsExisted();
}
}

As commenting,if I can partial mock the method "needToPartialMocked()",set it return false directly,in some test case,lots of mocking stuff can be cut away.

TestNotEqual panics

--- FAIL: TestNotEqual (0.00 seconds)
panic: runtime error: comparing uncomparable type []uint8 [recovered]
    panic: runtime error: comparing uncomparable type []uint8

goroutine 29 [running]:
runtime.panic(0x2cb920, 0xc208001090)
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/runtime/panic.c:279 +0xf5
testing.func·006()
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/testing/testing.go:416 +0x176
runtime.panic(0x2cb920, 0xc208001090)
    /usr/local/Cellar/go/1.3.3/libexec/src/pkg/runtime/panic.c:248 +0x18d
github.com/willfaught/testify/assert.ObjectsAreEqual(0x24b9a0, 0xc208048ae0, 0x24b9a0, 0xc208048b00, 0x18)
    /Users/Will/src/github.com/willfaught/testify/assert/assertions.go:43 +0x27d
github.com/willfaught/testify/assert.NotEqual(0x576990, 0xc20807a990, 0x24b9a0, 0xc208048ae0, 0x24b9a0, 0xc208048b00, 0x0, 0x0, 0x0, 0x1)
    /Users/Will/src/github.com/willfaught/testify/assert/assertions.go:429 +0x4a
github.com/willfaught/testify/assert.TestNotEqual(0xc20807a900)
    /Users/Will/src/github.com/willfaught/testify/assert/assertions_test.go:193 +0x6e2

This might be related to the recent breaking change in assert.ObjectsAreEqual.

Buildup/Teardown

Many testing libraries provide some method of defining common building up and tearing down functionality for the testing environment. I'm not sure if this type of functionality is something that would fit with the goals of testify, but it's a fairly common type of functionality that simplifies code for a number of use cases.

An example of a common case:

func BuildupTestEnv() {
    InsertToTestDB(testingData)
}

func TeardownTestEnv() {
    TruncateTestDB()
}

func TestGetWithID(t *testing.T) {
    BuildupTestEnv() // run at the beginning of every test
    [...testing code...]
    TeardownTestEnv() // run at the end of every test
}

The "go test" command doesn't provide anything like this, so most testing frameworks get around this by doing something like the following:

import (
    "testify"
)

type ControllerTestSuite struct{
    testify.Suite
}

// This function will be run by the "go test" command
func TestRun(t *testing.T) {
    suite := new(ControllerTestSuite)
    testify.RunSuite(suite)
}

// Run by testify.RunSuite(suite) before each test
func (suite *ControllerTestSuite) BeforeTest() {
    InsertToTestDB(testingData)
}

// Run by testify.RunSuite(suite) after each test
func (suite *ControllerTestSuite) AfterTest() {
    TruncateTestDB()
}

// Run by testify.RunSuite(suite) as a test, after running BeforeTest() but
// before running AfterTest()
func (suite *ControllerTestSuite) TestGetWithID() {
    [...testing code...]
}

Here are two example testing libraries in Go that support buildup and teardown methods, using the "go test" tool:

http://labix.org/gocheck (See: http://labix.org/gocheck#fixtures for buildup and teardown)

https://github.com/remogatto/prettytest (See: https://github.com/remogatto/prettytest/blob/master/prettytest_test.go#L102-120 for buildup and teardown)

AssertExpectations incorrectly claims additional call needed

AssertExpectations seems to miscount when using AnythingOfType:

package main

import (
    "github.com/stretchr/testify/mock"
    "testing"
)

type MyType struct {
}

type MyTypeReceiver struct {
    mock.Mock
}

func (mtr MyTypeReceiver) Fn(mytype *MyType) error {
    args := mtr.Mock.Called(mytype)
    return args.Error(0)
}

func TestAnythingOfTypeMock(t *testing.T) {
    mockReceiver := MyTypeReceiver{}
    mockReceiver.On("Fn", mock.AnythingOfType("*main.MyType")).Return(nil).Once()

    mockReceiver.Fn(&MyType{})

    if !mockReceiver.AssertExpectations(t) {
        t.Fail()
    }
}

output:

$ go test
--- FAIL: TestAnythingOfTypeMock (0.00 seconds)
    mock.go:249: ❌    Fn(mock.AnythingOfTypeArgument)
    mock.go:259: FAIL: 0 out of 1 expectation(s) were met.
            The code you are testing needs to make 1 more call(s).
            at: mock_test.go:26
FAIL
exit status 1
FAIL    _/home/rgarcia/debug    0.001s

Is it possible to replace *testing.T with an interface?

I think the mocking style of testify is more nature than gomock,and hope it can be hooked into ginkgo(a BDD framework:https://github.com/onsi),so posted a function request here:onsi/ginkgo#17 the developer of ginkgo said:


It looks like testify uses (*testing.T) directly instead of an interface (which gomock does). Ginkgo can provide such frameworks with a Fail function that one can wrap in such a way to satisfy most interfaces (this is how we support go mock), but *testing.T refers to a concrete type and passing in the testing.T for the test that Ginkgo runs in would cause the entire suite to fail should one of your mock assertions fail...


His suggestion(or needing) is:replaces *testing.T with an interface first,so question:is it possible?.

assert.Nil fails when a Value is returned (and not a pointer)

Hi --

got another one for you. I want to assert that a function does not
return an error:

err := doSomething()
fmt.Printf("err = %#v\n", err)
assert.Nil(t, err)

But if doSomething() really does return an error object, I get a panic
rather than a test failure:

=== RUN Test_no_error
err = runtime.MyError{}
--- PASS: Test_no_error (0.00 seconds)
panic: reflect: call of reflect.Value.IsNil on struct Value [recovered]
panic: reflect: call of reflect.Value.IsNil on struct Value

goroutine 12 [running]:
testing._func_003(0x7f8a934c5fa8, 0x7f8a934c5100, 0x7f8a934c5fb8,
0x7f8a934c5da0)
/usr/local/go/src/pkg/testing/testing.go:287 +0xf3
----- stack segment boundary -----
reflect.Value.IsNil(0x4de0f8, 0x7f8a936257e8, 0x190, 0x7f8a936257e8, 0x190, ...)
/usr/local/go/src/pkg/reflect/value.go:895 +0x130
github.com/stretchrcom/testify/assert.Nil(0xf84006f580, 0x4de0e8,
0x7f8a936257e8, 0x0, 0x0, ...)
/home/greg/src/fubsy/src/github.com/stretchrcom/testify/assert/assertions.go:204
+0xd3
fubsy/runtime.Test_no_error(0xf84006f580, 0x2f5c4098)
/home/greg/src/fubsy/src/fubsy/runtime/wtf_test.go:23 +0x111
testing.tRunner(0xf84006f580, 0x597520, 0x0, 0x0)
/usr/local/go/src/pkg/testing/testing.go:292 +0x6f
created by testing.RunTests
/usr/local/go/src/pkg/testing/testing.go:368 +0x795

I think it's because doSomething() returns a plain struct, not a
pointer to a struct. If I change it to return a pointer, testify works
fine: I get a nice clear test failure.

Here's my complete reproduction:

"""
package runtime

import (
"testing"
"fmt"
"github.com/stretchrcom/testify/assert"
)

type MyError struct {
}

func (self MyError) Error() string {
return "uh-oh"
}

func doSomething() error {
return MyError{}
}

func Test_no_error(t *testing.T) {
err := doSomething()
fmt.Printf("err = %#v\n", err)
assert.Nil(t, err)
}
"""

Is there a better way to assert that an error value is nil? Or should
I open a bug?

Thanks!

Greg

JUnit

Hi, how to use testify and junit log processors together?
I think it's a good idea to implement junit reporting

assert.Empty should work with channels

When passed a channel type, assert.Empty() checks if it is nil, but this is already well served with assert.Nil(). To me it seems to be idiomatic Go since you also use len to check for emptiness of both slices and channels. If you think that this is worthwhile to have, I can do a PR.

Introduce a standard `Fail` method

        t.Errorf("\r%s\r\tLocation:\t%s\n\r\tError:\t\tShould be true\n\r\tMessages:\t%s\n\r", getWhitespaceString(), CallerInfo(), message)

Put all of these into one place.

Empty() doesn't support checking empty maps.

Since maps are built-in types I figure this should be supported. But evidently, this is not the case.

Test

package main

import "testing"
import a "github.com/stretchr/testify/assert"

func TestEmpty(t *testing.T) {
    m := make(map[string]string)
    m["hello"] = "world"
    a.Empty(t, m, "map was not empty.")

    m = make(map[string]string)
    a.Empty(t, m, "map was empty.") // should pass, but fail
}

Result

--- FAIL: TestEmpty (0.00 seconds)
        Location:       main_test.go:9
        Error:          Should be empty, but was map[hello:world]
        Messages:       map was not empty.

        Location:       main_test.go:12
        Error:          Should be empty, but was map[]
        Messages:       map was empty.

FAIL
FAIL    _/Users/chakrit/Documents/go-scratch    0.010s

Expected

1st test should fails, as it is.
2nd test should pass.


I can ship a PR, if you agree. I believe a len(m) == 0 check would work just fine.

Much Simpler Testify

Greetings, everyone!

I have been thinking for a while about creating a much simpler version of testify.

My goals would be to:

  • Make the API much smaller
  • Make the output more compact - probably a single line like the standard testing framework
  • Use a require approach for all functions - abort if a test fails
  • Maintain the assert approach, with a require method that allows for a one-off require and fail. This will avoid deep nesting of if statements.
    • is.Equal(a,b).Require() or similar
  • Must manually output failure messages in the style of the testing framework, then call t.FailNow()
    • This will allow us to avoid using \r and \b which is incompatible with various output consoles.
    • Basically we need to duplicate the decorate
      function to generate our own output.
  • Remain completely dependent on the Go testing framework - testify should be as easy (or easier) to use as it is now... no fanciness.
  • Testify must take a testing.TB to enable testify usage in benchmark tests.

The reason this has been on my mind is because I usually use a very small subset of the available API in the current testify, and I feel that it may be getting a bit bloated. In addition, I feel that testify may be adding some overhead to the testing process, thus increasing the amount of time it takes to run tests. I really should get some data to back that up. In addition, testify was written a long time ago, when we were still young gophers. I feel it could be much cleaner. :)

I am still not sure this is something I will move forward with. I am hoping to get some feedback from the community to see what you think. Most likely this will live in its own subfolder as a separate package so the current version of testify doesn't just break for people currently using it.

I'd appreciate some feedback from all of you who use testify, if you would be so kind:

  • What functionality do you find yourself using the most?
  • What functionality could you simply not live without?
  • What is missing that you feel should be added?
  • What is in testify that you feel should be removed?
  • What is in testify that you feel could be improved?
  • Anything else?

Thanks in advance, everyone!

Error: Not equal: 6012 != 0x177c

Thought the values are equal in fact, testing framework gives an error about equality.

it happens with following code:
assert.Equal(t, event.GetSum(), uint64(6012))

Failing test in Mock - AssertExpectationsCustomType

I am checked out on master:bd93f0. When running tests for the mock package under go version 1.2 darwin/amd64, I am getting the following fail:

$ go test
--- FAIL: Test_Mock_AssertExpectationsCustomType (0.00 seconds)
        Location:       mock_test.go:406
    Error:      Should be true

FAIL
exit status 1
FAIL    github.com/stretchr/testify/mock    0.021s

All other package tests (suite, assert, testify) are running without fails.

Make assert.Nil and assert.NotNil work with strings

assert.NotNil(t, "") gives you "call of reflect.Value.IsNil on string Value"

In Go, technically strings cannot be nil, but we know what the developer means. They mean, is it an empty string?

We could add explicit support. OR we could add an assert.Empty and assert.NotEmpty that might use Nil checks but will also check for "" and []byte("") etc. In fact, maybe just len(x) == 0 - then it will work for arrays and slices too.

assert.NoError() message formatting is a little weird

In NoError, we use the Nil test, which makes an error message with %#v of error (which in my case prints out a lot of weirdly formatted stuff due to our custom error type which includes a stacktrace) and then it also prints the error's message as part of the message, thus populating Error: with a very poorly formatted and incomplete version of the Messages: field, and putting any custom message you pass to NoError print at the bottom of all of this.

How do you guys feel about using the nil test but not the formatting for it? In my opinion, it should be:
Error: Expected no error, but got: <%v of error>
Message:

I'll open a pull request.

Different behavior of go 1.3 and go 1.2.2

Method ObjectsAreEqual has this statement:
fmt.Sprintf("%#v", expected) == fmt.Sprintf("%#v", actual)

For fmt.Println(fmt.Sprintf("%#v", []byte{}), fmt.Sprintf("%#v", []byte(nil))) we have different behavior:
(golang-1.2.2) []byte{} []byte{}
(golang-1.3) []byte{} []byte(nil)

Link to github.com/vektra/mockery

This weekend I coded up a tool to auto generate mock code that uses github.com/stretchr/testify/mock. I'd love to get a link in the docs since using mockery makes using mocks much faster.

Can't clone this package with git.

I run: go get -u -v -x github.com/stretchr/goweb
It hangs trying to download github.com/stretchr/testify

I run: go get -u -v -x github.com/stretchr/testify
It hangs.

I run: git clone -v https://github.com/stretchr/testify
It says: Cloning into 'testify'...
And then it hangs

git version 1.7.9.6
go version go1.1.1 linux/amd64

How to use AnythingOfType?

I'm trying to use testify/mock but I'm having the following issue and I'm not even sure If I'm using it right.

I've put parts of the code I'm using bellow and the test output:

func TestMessageSender(t *testing.T) {
        connMock := new(RedisConnMock)
        connMock.On("Close").Return(nil).Once()
        connMock.On("Do", "PSTEX",
                mock.AnythingOfType("string"),
                mock.AnythingOfType("int64"),
                mock.AnythingOfType("string")).
                Return("OK", nil).
                Once()

...

mock: Unexpected Method Call
-----------------------------

Do(string,string,int64,string)
                0: PSETEX
                1: a1b427e4-f32a-34de-8165-d946c774981d
                2: 259200000
                3: {"uuid":"a1b427e4-f32a-34de-8165-d946c774981d"...}

The closest call I have is: 

Do(string,mock.AnythingOfTypeArgument,mock.AnythingOfTypeArgument,mock.AnythingOfTypeArgument)
                0: PSTEX
                1: string
                2: int64
                3: string

Can you please help me?

Mocking Variadic Functions

Hi there,

I get a strange error when mocking out a variadic function and calling it with a empty arguments list:

--- FAIL: TestStash (0.00 seconds)
panic:

mock: Unexpected Method Call
-----------------------------

Send(string,[]interface {})
        0: MULTI
        1: []

The closest call I have is:

Send(string,[]interface {})
        0: MULTI
        1: []
 [recovered]
    panic:

For context, I'm trying to mock out redigo.

type MockRedisConn struct {
    mock.Mock
}

func (m *MockRedisConn) Close() error {
    return nil
}

func (m *MockRedisConn) Err() error {
    return nil
}

func (m *MockRedisConn) Do(commandName string, argsList ...interface{}) (interface{}, error) {
    args := m.Mock.Called(commandName, argsList)
    return args.Get(0), args.Error(1)
}

func (m *MockRedisConn) Send(commandName string, argsList ...interface{}) error {
    args := m.Mock.Called(commandName, argsList)
    return args.Error(0)
}

func (m *MockRedisConn) Flush() error {
    return nil
}

func (m *MockRedisConn) Receive() (interface{}, error) {
    return nil, nil

}

I then declare an expectation for a method call with an empty argslist:

mockRedis.On("Send", "MULTI", []interface{}{}).Return(nil)

Is there a bug in how testify/mock handles variadic functions?

is there a typo in the `mock` package example?

In the following example code from the README --

// TestSomething is an example of how to use our test object to
// make assertions about some target code we are testing.
func TestSomething(t *testing.T) {

  // create an instance of our test object
  testObj := new(MyMockedObject)

  // setup expectations
  testObj.On("DoSomething", 123).Return(true, nil)

  // call the code we are testing
  targetFuncThatDoesSomethingWithObj(testObj)

  // assert that the expectations were met
  testObj.Mock.AssertExpectations(t)

}

should it actually be testObj.Mock.On("DoSomething")...?

Not a bug,but a suggestion:mocking should be overrideable

I am using a BDD framework that supports BeforeEach(),so I want to set some default mocking,then override needed mocking in concrete method,but I found mocking same method with same parameters but different returns,only first mock will work.So hoping mocking will be overrideable,and this will make test more concise for "big" method with many dependencies.

does not fullfil the standard of http.ResponseWriter

from: http://golang.org/pkg/net/http/#ResponseWriter

// Write writes the data to the connection as part of an HTTP reply.
// If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
// before writing the data.  If the Header does not contain a
// Content-Type line, Write adds a Content-Type set to the result of passing
// the initial 512 bytes of written data to DetectContentType.
Write([]byte) (int, error)

so when you call Write, you need set the response code to 200 if response code is 0

BDD pattern

As well as the assert pattern, we should consider adding a BDD style. Something like this:

func TestSomething(t *testing.T) {

  testify.It("Should do what it is told", func(t *testify.T){
    t.Expect(val).ToEqual(123)
    t.Expect(b).ToBeTrue()
  })

}

Thoughts?

Bug: Contains doesn't work for complex types

The following function passes the first test but fails the second:

type A struct {
    Name, Value string
}

func TestContains(t *testing.T) {
    assert := assert.New(t)

    a1 := []*A{
        &A{"b", "c"},
        &A{"d", "e"},
        &A{"g", "h"},
        &A{"j", "k"},
    }
    b := &A{"b", "c"}
    assert.Equal(a1[0], b)
    assert.Contains(a1, b)
}

That happens because includeElement does a naive comparison, instead of using ObjectsAreEqual.

Auto generate duplicated code from assertions

Hi there,

I recently discovered this awesome test tool, even tho I'm not a fan of external one, this is pretty useful to not be used 😄

I saw that you support (and thanks for that):

assert := assert.New(t)

Is there any particular reason why we don't have the same thing for require ?

Thanks again guys!

Testify not installed with `go test -i`

Unfortunately, testify doesn't get installed as a test dependency when running go test -i ./.... Instead, I have to manually run go get github.com/stretchr/testify before I can use it for any project.

This somewhat subverts the idea of (test) dependencies that are automatically installed, no?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.