How do I mock netconf session in unit tests Golang

219 views Asked by At

I am using juniper's netconf package ("github.com/Juniper/go-netconf/netconf") to establish a netconf session in my code.

I wanted to know how can I mock a netconf session in my unit tests.

My methods are:

func TestMyFunction(t *testing.T) {
    getSSHConnection = mockGetSSHConnection
    got := MyFunction()
    want := 123
    if !reflect.DeepEqual(got, want) {
        t.Errorf("Error expectation not met, want %v, got %v", want, got)
    }
}
func mockGetSSHConnection() (*netconf.Session, error) {
    var sess netconf.Session
    sess.SessionID = 123
    return &sess, nil
}

The problem arises when MyFunction() has a line that defers sess.Close() and it's throwing error due to nil pointer dereference

func MyFunction() int {
    sess, err := getSSHConnection() // returns (*netconf.Session, error)
    if err == nil && sess != nil {
        defer sess.Close() -> Problem happens here
        // Calls RPC here and rest of the code here
        
    } 
    return 0
}

So, what changes can I make on mockGetSSHConnection() method so that sess.Close() won't throw error?

2

There are 2 answers

0
Eelco On BEST ANSWER

The nil pointer error originates within the Close function when Close is called on the underlying Transport. Fortunately Transport is an interface type that you can easily mock and use in an actual instance of the netconf.Session. For example like so:

type MockTransport struct{}

func (t *MockTransport) Send([]byte) error {
    return nil
}

func (t *MockTransport) Receive() ([]byte, error) {
    return []byte{}, nil
}

func (t *MockTransport) Close() error {
    return nil
}

func (t *MockTransport) ReceiveHello() (*netconf.HelloMessage, error) {
    return &netconf.HelloMessage{SessionID: 123}, nil
}

func (t *MockTransport) SendHello(*netconf.HelloMessage) error {
    return nil
}

func (t *MockTransport) SetVersion(version string) {
}

func mockGetSSHConnection() (*netconf.Session, error) {
    t := MockTransport{}
    sess := netconf.NewSession(&t)
    return sess, nil
}

Note that the function you want to test currently return 0 and not the SessionID of the session. So you should fix that before the test is successful.

0
Mateusz Serafin On

You could use OOP and "github.com/stretchr/testify/mock" package

for example create

type SshClientMock struct {
    mock.Mock
}

func (s *SshClientMock) GetSSHConnection() {
    return //what do you need
}

in your unit test:

sshClient := SshClientMock
sshClient.On("GetSSHConnection").Return(what do you need)

and then call your method