// Code generated by MockGen. DO NOT EDIT.
// Source: git.fd.io/govpp.git/api (Interfaces: Channel)

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

import (
	api "git.fd.io/govpp.git/api"
	gomock "github.com/golang/mock/gomock"
	reflect "reflect"
	time "time"
)

// MockChannel is a mock of Channel interface
type MockChannel struct {
	ctrl     *gomock.Controller
	recorder *MockChannelMockRecorder
}

// MockChannelMockRecorder is the mock recorder for MockChannel
type MockChannelMockRecorder struct {
	mock *MockChannel
}

// NewMockChannel creates a new mock instance
func NewMockChannel(ctrl *gomock.Controller) *MockChannel {
	mock := &MockChannel{ctrl: ctrl}
	mock.recorder = &MockChannelMockRecorder{mock}
	return mock
}

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

// Close mocks base method
func (m *MockChannel) Close() {
	m.ctrl.Call(m, "Close")
}

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

// SendMultiRequest mocks base method
func (m *MockChannel) SendMultiRequest(arg0 api.Message) api.MultiRequestCtx {
	ret := m.ctrl.Call(m, "SendMultiRequest", arg0)
	ret0, _ := ret[0].(api.MultiRequestCtx)
	return ret0
}

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

// SendRequest mocks base method
func (m *MockChannel) SendRequest(arg0 api.Message) api.RequestCtx {
	ret := m.ctrl.Call(m, "SendRequest", arg0)
	ret0, _ := ret[0].(api.RequestCtx)
	return ret0
}

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

// SetReplyTimeout mocks base method
func (m *MockChannel) SetReplyTimeout(arg0 time.Duration) {
	m.ctrl.Call(m, "SetReplyTimeout", arg0)
}

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

// SubscribeNotification mocks base method
func (m *MockChannel) SubscribeNotification(arg0 chan api.Message, arg1 api.Message) (api.SubscriptionCtx, error) {
	ret := m.ctrl.Call(m, "SubscribeNotification", arg0, arg1)
	ret0, _ := ret[0].(api.SubscriptionCtx)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// SubscribeNotification indicates an expected call of SubscribeNotification
func (mr *MockChannelMockRecorder) SubscribeNotification(arg0, arg1 interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeNotification", reflect.TypeOf((*MockChannel)(nil).SubscribeNotification), arg0, arg1)
}
