/*
 * 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"

// MockPDUOption is an autogenerated mock type for the PDUOption type
type MockPDUOption struct {
	mock.Mock
}

type MockPDUOption_Expecter struct {
	mock *mock.Mock
}

func (_m *MockPDUOption) EXPECT() *MockPDUOption_Expecter {
	return &MockPDUOption_Expecter{mock: &_m.Mock}
}

// Execute provides a mock function with given fields: pdu
func (_m *MockPDUOption) Execute(pdu *PDU) {
	_m.Called(pdu)
}

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

// Execute is a helper method to define mock.On call
//   - pdu *PDU
func (_e *MockPDUOption_Expecter) Execute(pdu interface{}) *MockPDUOption_Execute_Call {
	return &MockPDUOption_Execute_Call{Call: _e.mock.On("Execute", pdu)}
}

func (_c *MockPDUOption_Execute_Call) Run(run func(pdu *PDU)) *MockPDUOption_Execute_Call {
	_c.Call.Run(func(args mock.Arguments) {
		run(args[0].(*PDU))
	})
	return _c
}

func (_c *MockPDUOption_Execute_Call) Return() *MockPDUOption_Execute_Call {
	_c.Call.Return()
	return _c
}

func (_c *MockPDUOption_Execute_Call) RunAndReturn(run func(*PDU)) *MockPDUOption_Execute_Call {
	_c.Call.Return(run)
	return _c
}

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

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

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

	return mock
}
