//
// 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: ./cloudstack/AccountService.go
//
// Generated by this command:
//
//	mockgen -destination=./cloudstack/AccountService_mock.go -package=cloudstack -copyright_file=header.txt -source=./cloudstack/AccountService.go
//

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

import (
	reflect "reflect"

	gomock "go.uber.org/mock/gomock"
)

// MockAccountServiceIface is a mock of AccountServiceIface interface.
type MockAccountServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockAccountServiceIfaceMockRecorder
	isgomock struct{}
}

// MockAccountServiceIfaceMockRecorder is the mock recorder for MockAccountServiceIface.
type MockAccountServiceIfaceMockRecorder struct {
	mock *MockAccountServiceIface
}

// NewMockAccountServiceIface creates a new mock instance.
func NewMockAccountServiceIface(ctrl *gomock.Controller) *MockAccountServiceIface {
	mock := &MockAccountServiceIface{ctrl: ctrl}
	mock.recorder = &MockAccountServiceIfaceMockRecorder{mock}
	return mock
}

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

// CreateAccount mocks base method.
func (m *MockAccountServiceIface) CreateAccount(p *CreateAccountParams) (*CreateAccountResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateAccount", p)
	ret0, _ := ret[0].(*CreateAccountResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CreateAccount indicates an expected call of CreateAccount.
func (mr *MockAccountServiceIfaceMockRecorder) CreateAccount(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateAccount", reflect.TypeOf((*MockAccountServiceIface)(nil).CreateAccount), p)
}

// DeleteAccount mocks base method.
func (m *MockAccountServiceIface) DeleteAccount(p *DeleteAccountParams) (*DeleteAccountResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteAccount", p)
	ret0, _ := ret[0].(*DeleteAccountResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeleteAccount indicates an expected call of DeleteAccount.
func (mr *MockAccountServiceIfaceMockRecorder) DeleteAccount(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAccount", reflect.TypeOf((*MockAccountServiceIface)(nil).DeleteAccount), p)
}

// DisableAccount mocks base method.
func (m *MockAccountServiceIface) DisableAccount(p *DisableAccountParams) (*DisableAccountResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DisableAccount", p)
	ret0, _ := ret[0].(*DisableAccountResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DisableAccount indicates an expected call of DisableAccount.
func (mr *MockAccountServiceIfaceMockRecorder) DisableAccount(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableAccount", reflect.TypeOf((*MockAccountServiceIface)(nil).DisableAccount), p)
}

// EnableAccount mocks base method.
func (m *MockAccountServiceIface) EnableAccount(p *EnableAccountParams) (*EnableAccountResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "EnableAccount", p)
	ret0, _ := ret[0].(*EnableAccountResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// EnableAccount indicates an expected call of EnableAccount.
func (mr *MockAccountServiceIfaceMockRecorder) EnableAccount(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableAccount", reflect.TypeOf((*MockAccountServiceIface)(nil).EnableAccount), p)
}

// GetAccountByID mocks base method.
func (m *MockAccountServiceIface) GetAccountByID(id string, opts ...OptionFunc) (*Account, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{id}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetAccountByID", varargs...)
	ret0, _ := ret[0].(*Account)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetAccountByID indicates an expected call of GetAccountByID.
func (mr *MockAccountServiceIfaceMockRecorder) GetAccountByID(id any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{id}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccountByID", reflect.TypeOf((*MockAccountServiceIface)(nil).GetAccountByID), varargs...)
}

// GetAccountByName mocks base method.
func (m *MockAccountServiceIface) GetAccountByName(name string, opts ...OptionFunc) (*Account, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{name}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetAccountByName", varargs...)
	ret0, _ := ret[0].(*Account)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetAccountByName indicates an expected call of GetAccountByName.
func (mr *MockAccountServiceIfaceMockRecorder) GetAccountByName(name any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccountByName", reflect.TypeOf((*MockAccountServiceIface)(nil).GetAccountByName), varargs...)
}

// GetAccountID mocks base method.
func (m *MockAccountServiceIface) GetAccountID(name string, opts ...OptionFunc) (string, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{name}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetAccountID", varargs...)
	ret0, _ := ret[0].(string)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetAccountID indicates an expected call of GetAccountID.
func (mr *MockAccountServiceIfaceMockRecorder) GetAccountID(name any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccountID", reflect.TypeOf((*MockAccountServiceIface)(nil).GetAccountID), varargs...)
}

// GetProjectAccountID mocks base method.
func (m *MockAccountServiceIface) GetProjectAccountID(keyword, projectid string, opts ...OptionFunc) (string, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{keyword, projectid}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetProjectAccountID", varargs...)
	ret0, _ := ret[0].(string)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetProjectAccountID indicates an expected call of GetProjectAccountID.
func (mr *MockAccountServiceIfaceMockRecorder) GetProjectAccountID(keyword, projectid any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{keyword, projectid}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProjectAccountID", reflect.TypeOf((*MockAccountServiceIface)(nil).GetProjectAccountID), varargs...)
}

// IsAccountAllowedToCreateOfferingsWithTags mocks base method.
func (m *MockAccountServiceIface) IsAccountAllowedToCreateOfferingsWithTags(p *IsAccountAllowedToCreateOfferingsWithTagsParams) (*IsAccountAllowedToCreateOfferingsWithTagsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "IsAccountAllowedToCreateOfferingsWithTags", p)
	ret0, _ := ret[0].(*IsAccountAllowedToCreateOfferingsWithTagsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// IsAccountAllowedToCreateOfferingsWithTags indicates an expected call of IsAccountAllowedToCreateOfferingsWithTags.
func (mr *MockAccountServiceIfaceMockRecorder) IsAccountAllowedToCreateOfferingsWithTags(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsAccountAllowedToCreateOfferingsWithTags", reflect.TypeOf((*MockAccountServiceIface)(nil).IsAccountAllowedToCreateOfferingsWithTags), p)
}

// LinkAccountToLdap mocks base method.
func (m *MockAccountServiceIface) LinkAccountToLdap(p *LinkAccountToLdapParams) (*LinkAccountToLdapResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "LinkAccountToLdap", p)
	ret0, _ := ret[0].(*LinkAccountToLdapResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// LinkAccountToLdap indicates an expected call of LinkAccountToLdap.
func (mr *MockAccountServiceIfaceMockRecorder) LinkAccountToLdap(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LinkAccountToLdap", reflect.TypeOf((*MockAccountServiceIface)(nil).LinkAccountToLdap), p)
}

// ListAccounts mocks base method.
func (m *MockAccountServiceIface) ListAccounts(p *ListAccountsParams) (*ListAccountsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListAccounts", p)
	ret0, _ := ret[0].(*ListAccountsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListAccounts indicates an expected call of ListAccounts.
func (mr *MockAccountServiceIfaceMockRecorder) ListAccounts(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAccounts", reflect.TypeOf((*MockAccountServiceIface)(nil).ListAccounts), p)
}

// ListProjectAccounts mocks base method.
func (m *MockAccountServiceIface) ListProjectAccounts(p *ListProjectAccountsParams) (*ListProjectAccountsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListProjectAccounts", p)
	ret0, _ := ret[0].(*ListProjectAccountsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListProjectAccounts indicates an expected call of ListProjectAccounts.
func (mr *MockAccountServiceIfaceMockRecorder) ListProjectAccounts(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListProjectAccounts", reflect.TypeOf((*MockAccountServiceIface)(nil).ListProjectAccounts), p)
}

// LockAccount mocks base method.
func (m *MockAccountServiceIface) LockAccount(p *LockAccountParams) (*LockAccountResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "LockAccount", p)
	ret0, _ := ret[0].(*LockAccountResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// LockAccount indicates an expected call of LockAccount.
func (mr *MockAccountServiceIfaceMockRecorder) LockAccount(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockAccount", reflect.TypeOf((*MockAccountServiceIface)(nil).LockAccount), p)
}

// MarkDefaultZoneForAccount mocks base method.
func (m *MockAccountServiceIface) MarkDefaultZoneForAccount(p *MarkDefaultZoneForAccountParams) (*MarkDefaultZoneForAccountResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "MarkDefaultZoneForAccount", p)
	ret0, _ := ret[0].(*MarkDefaultZoneForAccountResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// MarkDefaultZoneForAccount indicates an expected call of MarkDefaultZoneForAccount.
func (mr *MockAccountServiceIfaceMockRecorder) MarkDefaultZoneForAccount(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarkDefaultZoneForAccount", reflect.TypeOf((*MockAccountServiceIface)(nil).MarkDefaultZoneForAccount), p)
}

// NewCreateAccountParams mocks base method.
func (m *MockAccountServiceIface) NewCreateAccountParams(email, firstname, lastname, password, username string) *CreateAccountParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreateAccountParams", email, firstname, lastname, password, username)
	ret0, _ := ret[0].(*CreateAccountParams)
	return ret0
}

// NewCreateAccountParams indicates an expected call of NewCreateAccountParams.
func (mr *MockAccountServiceIfaceMockRecorder) NewCreateAccountParams(email, firstname, lastname, password, username any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateAccountParams", reflect.TypeOf((*MockAccountServiceIface)(nil).NewCreateAccountParams), email, firstname, lastname, password, username)
}

// NewDeleteAccountParams mocks base method.
func (m *MockAccountServiceIface) NewDeleteAccountParams(id string) *DeleteAccountParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDeleteAccountParams", id)
	ret0, _ := ret[0].(*DeleteAccountParams)
	return ret0
}

// NewDeleteAccountParams indicates an expected call of NewDeleteAccountParams.
func (mr *MockAccountServiceIfaceMockRecorder) NewDeleteAccountParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteAccountParams", reflect.TypeOf((*MockAccountServiceIface)(nil).NewDeleteAccountParams), id)
}

// NewDisableAccountParams mocks base method.
func (m *MockAccountServiceIface) NewDisableAccountParams(lock bool) *DisableAccountParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDisableAccountParams", lock)
	ret0, _ := ret[0].(*DisableAccountParams)
	return ret0
}

// NewDisableAccountParams indicates an expected call of NewDisableAccountParams.
func (mr *MockAccountServiceIfaceMockRecorder) NewDisableAccountParams(lock any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDisableAccountParams", reflect.TypeOf((*MockAccountServiceIface)(nil).NewDisableAccountParams), lock)
}

// NewEnableAccountParams mocks base method.
func (m *MockAccountServiceIface) NewEnableAccountParams() *EnableAccountParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewEnableAccountParams")
	ret0, _ := ret[0].(*EnableAccountParams)
	return ret0
}

// NewEnableAccountParams indicates an expected call of NewEnableAccountParams.
func (mr *MockAccountServiceIfaceMockRecorder) NewEnableAccountParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewEnableAccountParams", reflect.TypeOf((*MockAccountServiceIface)(nil).NewEnableAccountParams))
}

// NewIsAccountAllowedToCreateOfferingsWithTagsParams mocks base method.
func (m *MockAccountServiceIface) NewIsAccountAllowedToCreateOfferingsWithTagsParams() *IsAccountAllowedToCreateOfferingsWithTagsParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewIsAccountAllowedToCreateOfferingsWithTagsParams")
	ret0, _ := ret[0].(*IsAccountAllowedToCreateOfferingsWithTagsParams)
	return ret0
}

// NewIsAccountAllowedToCreateOfferingsWithTagsParams indicates an expected call of NewIsAccountAllowedToCreateOfferingsWithTagsParams.
func (mr *MockAccountServiceIfaceMockRecorder) NewIsAccountAllowedToCreateOfferingsWithTagsParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIsAccountAllowedToCreateOfferingsWithTagsParams", reflect.TypeOf((*MockAccountServiceIface)(nil).NewIsAccountAllowedToCreateOfferingsWithTagsParams))
}

// NewLinkAccountToLdapParams mocks base method.
func (m *MockAccountServiceIface) NewLinkAccountToLdapParams(account, domainid, ldapdomain string) *LinkAccountToLdapParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewLinkAccountToLdapParams", account, domainid, ldapdomain)
	ret0, _ := ret[0].(*LinkAccountToLdapParams)
	return ret0
}

// NewLinkAccountToLdapParams indicates an expected call of NewLinkAccountToLdapParams.
func (mr *MockAccountServiceIfaceMockRecorder) NewLinkAccountToLdapParams(account, domainid, ldapdomain any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewLinkAccountToLdapParams", reflect.TypeOf((*MockAccountServiceIface)(nil).NewLinkAccountToLdapParams), account, domainid, ldapdomain)
}

// NewListAccountsParams mocks base method.
func (m *MockAccountServiceIface) NewListAccountsParams() *ListAccountsParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListAccountsParams")
	ret0, _ := ret[0].(*ListAccountsParams)
	return ret0
}

// NewListAccountsParams indicates an expected call of NewListAccountsParams.
func (mr *MockAccountServiceIfaceMockRecorder) NewListAccountsParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListAccountsParams", reflect.TypeOf((*MockAccountServiceIface)(nil).NewListAccountsParams))
}

// NewListProjectAccountsParams mocks base method.
func (m *MockAccountServiceIface) NewListProjectAccountsParams(projectid string) *ListProjectAccountsParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListProjectAccountsParams", projectid)
	ret0, _ := ret[0].(*ListProjectAccountsParams)
	return ret0
}

// NewListProjectAccountsParams indicates an expected call of NewListProjectAccountsParams.
func (mr *MockAccountServiceIfaceMockRecorder) NewListProjectAccountsParams(projectid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListProjectAccountsParams", reflect.TypeOf((*MockAccountServiceIface)(nil).NewListProjectAccountsParams), projectid)
}

// NewLockAccountParams mocks base method.
func (m *MockAccountServiceIface) NewLockAccountParams(account, domainid string) *LockAccountParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewLockAccountParams", account, domainid)
	ret0, _ := ret[0].(*LockAccountParams)
	return ret0
}

// NewLockAccountParams indicates an expected call of NewLockAccountParams.
func (mr *MockAccountServiceIfaceMockRecorder) NewLockAccountParams(account, domainid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewLockAccountParams", reflect.TypeOf((*MockAccountServiceIface)(nil).NewLockAccountParams), account, domainid)
}

// NewMarkDefaultZoneForAccountParams mocks base method.
func (m *MockAccountServiceIface) NewMarkDefaultZoneForAccountParams(account, domainid, zoneid string) *MarkDefaultZoneForAccountParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewMarkDefaultZoneForAccountParams", account, domainid, zoneid)
	ret0, _ := ret[0].(*MarkDefaultZoneForAccountParams)
	return ret0
}

// NewMarkDefaultZoneForAccountParams indicates an expected call of NewMarkDefaultZoneForAccountParams.
func (mr *MockAccountServiceIfaceMockRecorder) NewMarkDefaultZoneForAccountParams(account, domainid, zoneid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewMarkDefaultZoneForAccountParams", reflect.TypeOf((*MockAccountServiceIface)(nil).NewMarkDefaultZoneForAccountParams), account, domainid, zoneid)
}

// NewUpdateAccountParams mocks base method.
func (m *MockAccountServiceIface) NewUpdateAccountParams() *UpdateAccountParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewUpdateAccountParams")
	ret0, _ := ret[0].(*UpdateAccountParams)
	return ret0
}

// NewUpdateAccountParams indicates an expected call of NewUpdateAccountParams.
func (mr *MockAccountServiceIfaceMockRecorder) NewUpdateAccountParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdateAccountParams", reflect.TypeOf((*MockAccountServiceIface)(nil).NewUpdateAccountParams))
}

// UpdateAccount mocks base method.
func (m *MockAccountServiceIface) UpdateAccount(p *UpdateAccountParams) (*UpdateAccountResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateAccount", p)
	ret0, _ := ret[0].(*UpdateAccountResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateAccount indicates an expected call of UpdateAccount.
func (mr *MockAccountServiceIfaceMockRecorder) UpdateAccount(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAccount", reflect.TypeOf((*MockAccountServiceIface)(nil).UpdateAccount), p)
}
