package main
import (
"net/http"
"sync"
"time"
)
type SessionInterface1 interface {
doLoginAndReadDestinations1() bool
}
type Session1 struct {
sessionCookie string
mux sync.Mutex
sessionTime time.Time
targetAddress string
currentJwt string
transport *http.Transport
}
var currentSession1 Session1
func main() {
currentSession1.verifyLogin1()
}
func (s *Session1) doLoginAndReadDestinations1() bool {
..logic...
... for example return true
}
func callDest1(si SessionInterface1) bool {
return si.doLoginAndReadDestinations1()
}
func (s *Session1) verifyLogin1() bool {
return callDest1(s)
}
I want to create unit test and to mock doLoginAndReadDestinations1 I tried to create interface for this method and I create test
func test1(t *testing.T) {
type args struct {
}
tests := []struct {
name string
args args
want bool
}{{
name: "test",
args: args{},
want: false,
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var s1 *Session1
count := 10
s1 = &Session1{"", sync.Mutex{}, time.Now(), "", "", nil}
var got1 = s1.verifyLogin()
if got1 != tt.want {
t.Errorf("getJwt() = %v, want %v", got, tt.want)
}
})
}
}
I didn't know how I can change the logic of function doLoginAndReadDestinations1 in the test and to change the logic in the first main
You will need to abstract everything you want to mock. Instead of resolving dependency as a concrete implementation, use an interface. Then you will be able to create a mock which will implement this interface.
Generally, I would suggest you stretchr/testify for testing. It has methods for :
This library will help you structuring test, writing tests and remove your boilerplate code. It has mocking mechanisms inside. Read about mocking interfaces at testify mock section
In your unit test, you're only calling methods on Session1
, not on something that calls Session1
's methods; so there isn't anything to mock. When using mocking for tests, you don't mock methods, you mock types, when those types are dependencies of the type under test. For example, if you have a type Foo
which depends on (calls methods of) a type Bar
, and you want to test Foo
in isolation, you would create a mock of type Bar
, and in your tests for Foo
, you'd give it your BarMock
instead of Bar
. In your real code, you'd give it the real Bar
. There is no way to mock a single method of a type.
You might find this StackOverflow question and its extensive answers helpful.