/*
 * 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: rejected_execution_handler.go

// Package filter is a generated GoMock package.
package handler

import (
	reflect "reflect"
)

import (
	gomock "github.com/golang/mock/gomock"
)

import (
	common "github.com/apache/dubbo-go/common"
	protocol "github.com/apache/dubbo-go/protocol"
)

// MockRejectedExecutionHandler is a mock of RejectedExecutionHandler interface
type MockRejectedExecutionHandler struct {
	ctrl     *gomock.Controller
	recorder *MockRejectedExecutionHandlerMockRecorder
}

// MockRejectedExecutionHandlerMockRecorder is the mock recorder for MockRejectedExecutionHandler
type MockRejectedExecutionHandlerMockRecorder struct {
	mock *MockRejectedExecutionHandler
}

// NewMockRejectedExecutionHandler creates a new mock instance
func NewMockRejectedExecutionHandler(ctrl *gomock.Controller) *MockRejectedExecutionHandler {
	mock := &MockRejectedExecutionHandler{ctrl: ctrl}
	mock.recorder = &MockRejectedExecutionHandlerMockRecorder{mock}
	return mock
}

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

// RejectedExecution mocks base method
func (m *MockRejectedExecutionHandler) RejectedExecution(url *common.URL, invocation protocol.Invocation) protocol.Result {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "RejectedExecution", url, invocation)
	ret0, _ := ret[0].(protocol.Result)
	return ret0
}

// RejectedExecution indicates an expected call of RejectedExecution
func (mr *MockRejectedExecutionHandlerMockRecorder) RejectedExecution(url, invocation interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RejectedExecution", reflect.TypeOf((*MockRejectedExecutionHandler)(nil).RejectedExecution), url, invocation)
}
