/*
 * 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
 *
 *   https://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 mockery v2.28.2. DO NOT EDIT.

package bacnetip

import mock "github.com/stretchr/testify/mock"

// mockOption is an autogenerated mock type for the option type
type mockOption struct {
	mock.Mock
}

type mockOption_Expecter struct {
	mock *mock.Mock
}

func (_m *mockOption) EXPECT() *mockOption_Expecter {
	return &mockOption_Expecter{mock: &_m.Mock}
}

// Execute provides a mock function with given fields: specificOptions
func (_m *mockOption) Execute(specificOptions *protocolSpecificOptions) error {
	ret := _m.Called(specificOptions)

	var r0 error
	if rf, ok := ret.Get(0).(func(*protocolSpecificOptions) error); ok {
		r0 = rf(specificOptions)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// mockOption_Execute_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Execute'
type mockOption_Execute_Call struct {
	*mock.Call
}

// Execute is a helper method to define mock.On call
//   - specificOptions *protocolSpecificOptions
func (_e *mockOption_Expecter) Execute(specificOptions interface{}) *mockOption_Execute_Call {
	return &mockOption_Execute_Call{Call: _e.mock.On("Execute", specificOptions)}
}

func (_c *mockOption_Execute_Call) Run(run func(specificOptions *protocolSpecificOptions)) *mockOption_Execute_Call {
	_c.Call.Run(func(args mock.Arguments) {
		run(args[0].(*protocolSpecificOptions))
	})
	return _c
}

func (_c *mockOption_Execute_Call) Return(_a0 error) *mockOption_Execute_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *mockOption_Execute_Call) RunAndReturn(run func(*protocolSpecificOptions) error) *mockOption_Execute_Call {
	_c.Call.Return(run)
	return _c
}

type mockConstructorTestingTnewMockOption interface {
	mock.TestingT
	Cleanup(func())
}

// newMockOption creates a new instance of mockOption. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func newMockOption(t mockConstructorTestingTnewMockOption) *mockOption {
	mock := &mockOption{}
	mock.Mock.Test(t)

	t.Cleanup(func() { mock.AssertExpectations(t) })

	return mock
}
