我使用juniper的netconf包("github.com/Juniper/go-netconf/netconf")在我的代码中建立一个netconf会话。
我想知道如何在单元测试中模拟netconf会话。
我的方法是:
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
}
当MyFunction()有一行延迟了session . close()并且由于nil指针解引用而抛出错误时,问题就出现了
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
}
那么,我可以对mockGetSSHConnection()方法进行哪些更改,以便sess.Close()不会抛出错误?
当Close
在底层Transport
上被调用时,nil
指针错误产生于Close
函数内。幸运的是,Transport
是一种interface
类型,您可以轻松地在netconf.Session
的实际实例中模拟和使用它。例如:
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
}
请注意,您想要测试的函数当前返回0
,而不是会话的SessionID
。所以你应该在测试成功之前解决这个问题。
您可以使用OOP和"github.com/stretchr/testify/mock"包
例如create
type SshClientMock struct {
mock.Mock
}
func (s *SshClientMock) GetSSHConnection() {
return //what do you need
}
单元测试中的:
sshClient := SshClientMock
sshClient.On("GetSSHConnection").Return(what do you need)
然后调用你的方法