/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by MockGen. DO NOT EDIT.
// Source: remote_client.go

// Package remote is a generated GoMock package.
package remote

import (
	context "context"
	reflect "reflect"

	primitive "github.com/apache/rocketmq-client-go/v2/primitive"
	gomock "github.com/golang/mock/gomock"
)

// MockRemotingClient is a mock of RemotingClient interface
type MockRemotingClient struct {
	ctrl     *gomock.Controller
	recorder *MockRemotingClientMockRecorder
}

// MockRemotingClientMockRecorder is the mock recorder for MockRemotingClient
type MockRemotingClientMockRecorder struct {
	mock *MockRemotingClient
}

// NewMockRemotingClient creates a new mock instance
func NewMockRemotingClient(ctrl *gomock.Controller) *MockRemotingClient {
	mock := &MockRemotingClient{ctrl: ctrl}
	mock.recorder = &MockRemotingClientMockRecorder{mock}
	return mock
}

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

// RegisterRequestFunc mocks base method
func (m *MockRemotingClient) RegisterRequestFunc(code int16, f ClientRequestFunc) {
	m.ctrl.Call(m, "RegisterRequestFunc", code, f)
}

// RegisterRequestFunc indicates an expected call of RegisterRequestFunc
func (mr *MockRemotingClientMockRecorder) RegisterRequestFunc(code, f interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterRequestFunc", reflect.TypeOf((*MockRemotingClient)(nil).RegisterRequestFunc), code, f)
}

// RegisterInterceptor mocks base method
func (m *MockRemotingClient) RegisterInterceptor(interceptors ...primitive.Interceptor) {
	varargs := []interface{}{}
	for _, a := range interceptors {
		varargs = append(varargs, a)
	}
	m.ctrl.Call(m, "RegisterInterceptor", varargs...)
}

// RegisterInterceptor indicates an expected call of RegisterInterceptor
func (mr *MockRemotingClientMockRecorder) RegisterInterceptor(interceptors ...interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterInterceptor", reflect.TypeOf((*MockRemotingClient)(nil).RegisterInterceptor), interceptors...)
}

// InvokeSync mocks base method
func (m *MockRemotingClient) InvokeSync(ctx context.Context, addr string, request *RemotingCommand) (*RemotingCommand, error) {
	ret := m.ctrl.Call(m, "InvokeSync", ctx, addr, request)
	ret0, _ := ret[0].(*RemotingCommand)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// InvokeSync indicates an expected call of InvokeSync
func (mr *MockRemotingClientMockRecorder) InvokeSync(ctx, addr, request interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InvokeSync", reflect.TypeOf((*MockRemotingClient)(nil).InvokeSync), ctx, addr, request)
}

// InvokeAsync mocks base method
func (m *MockRemotingClient) InvokeAsync(ctx context.Context, addr string, request *RemotingCommand, callback func(*ResponseFuture)) error {
	ret := m.ctrl.Call(m, "InvokeAsync", ctx, addr, request, callback)
	ret0, _ := ret[0].(error)
	return ret0
}

// InvokeAsync indicates an expected call of InvokeAsync
func (mr *MockRemotingClientMockRecorder) InvokeAsync(ctx, addr, request, callback interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InvokeAsync", reflect.TypeOf((*MockRemotingClient)(nil).InvokeAsync), ctx, addr, request, callback)
}

// InvokeOneWay mocks base method
func (m *MockRemotingClient) InvokeOneWay(ctx context.Context, addr string, request *RemotingCommand) error {
	ret := m.ctrl.Call(m, "InvokeOneWay", ctx, addr, request)
	ret0, _ := ret[0].(error)
	return ret0
}

// InvokeOneWay indicates an expected call of InvokeOneWay
func (mr *MockRemotingClientMockRecorder) InvokeOneWay(ctx, addr, request interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InvokeOneWay", reflect.TypeOf((*MockRemotingClient)(nil).InvokeOneWay), ctx, addr, request)
}

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

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