// Code generated by MockGen. DO NOT EDIT.
// Source: git.fd.io/govpp.git/adapter (interfaces: StatsAPI)

// Package mock_adapter is a generated GoMock package.
package main

import (
	reflect "reflect"

	adapter "git.fd.io/govpp.git/adapter"
	gomock "github.com/golang/mock/gomock"
)

// MockStatsAPI is a mock of StatsAPI interface
type MockStatsAPI struct {
	ctrl     *gomock.Controller
	recorder *MockStatsAPIMockRecorder
}

// MockStatsAPIMockRecorder is the mock recorder for MockStatsAPI
type MockStatsAPIMockRecorder struct {
	mock *MockStatsAPI
}

// NewMockStatsAPI creates a new mock instance
func NewMockStatsAPI(ctrl *gomock.Controller) *MockStatsAPI {
	mock := &MockStatsAPI{ctrl: ctrl}
	mock.recorder = &MockStatsAPIMockRecorder{mock}
	return mock
}

// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockStatsAPI) EXPECT() *MockStatsAPIMockRecorder {
	return m.recorder
}

// Connect mocks base method
func (m *MockStatsAPI) Connect() error {
	ret := m.ctrl.Call(m, "Connect")
	ret0, _ := ret[0].(error)
	return ret0
}

// Connect indicates an expected call of Connect
func (mr *MockStatsAPIMockRecorder) Connect() *gomock.Call {
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connect", reflect.TypeOf((*MockStatsAPI)(nil).Connect))
}

// Disconnect mocks base method
func (m *MockStatsAPI) Disconnect() error {
	ret := m.ctrl.Call(m, "Disconnect")
	ret0, _ := ret[0].(error)
	return ret0
}

// Disconnect indicates an expected call of Disconnect
func (mr *MockStatsAPIMockRecorder) Disconnect() *gomock.Call {
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Disconnect", reflect.TypeOf((*MockStatsAPI)(nil).Disconnect))
}

// DumpStats mocks base method
func (m *MockStatsAPI) DumpStats(arg0 ...string) ([]*adapter.StatEntry, error) {
	varargs := []interface{}{}
	for _, a := range arg0 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "DumpStats", varargs...)
	ret0, _ := ret[0].([]*adapter.StatEntry)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DumpStats indicates an expected call of DumpStats
func (mr *MockStatsAPIMockRecorder) DumpStats(arg0 ...interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DumpStats", reflect.TypeOf((*MockStatsAPI)(nil).DumpStats), arg0...)
}

// ListStats mocks base method
func (m *MockStatsAPI) ListStats(arg0 ...string) ([]string, error) {
	varargs := []interface{}{}
	for _, a := range arg0 {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListStats", varargs...)
	ret0, _ := ret[0].([]string)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListStats indicates an expected call of ListStats
func (mr *MockStatsAPIMockRecorder) ListStats(arg0 ...interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListStats", reflect.TypeOf((*MockStatsAPI)(nil).ListStats), arg0...)
}
