//
// 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/AsyncjobService.go

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

import (
	reflect "reflect"

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

// MockAsyncjobServiceIface is a mock of AsyncjobServiceIface interface.
type MockAsyncjobServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockAsyncjobServiceIfaceMockRecorder
}

// MockAsyncjobServiceIfaceMockRecorder is the mock recorder for MockAsyncjobServiceIface.
type MockAsyncjobServiceIfaceMockRecorder struct {
	mock *MockAsyncjobServiceIface
}

// NewMockAsyncjobServiceIface creates a new mock instance.
func NewMockAsyncjobServiceIface(ctrl *gomock.Controller) *MockAsyncjobServiceIface {
	mock := &MockAsyncjobServiceIface{ctrl: ctrl}
	mock.recorder = &MockAsyncjobServiceIfaceMockRecorder{mock}
	return mock
}

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

// ListAsyncJobs mocks base method.
func (m *MockAsyncjobServiceIface) ListAsyncJobs(p *ListAsyncJobsParams) (*ListAsyncJobsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListAsyncJobs", p)
	ret0, _ := ret[0].(*ListAsyncJobsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListAsyncJobs indicates an expected call of ListAsyncJobs.
func (mr *MockAsyncjobServiceIfaceMockRecorder) ListAsyncJobs(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAsyncJobs", reflect.TypeOf((*MockAsyncjobServiceIface)(nil).ListAsyncJobs), p)
}

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

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

// NewQueryAsyncJobResultParams mocks base method.
func (m *MockAsyncjobServiceIface) NewQueryAsyncJobResultParams(jobid string) *QueryAsyncJobResultParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewQueryAsyncJobResultParams", jobid)
	ret0, _ := ret[0].(*QueryAsyncJobResultParams)
	return ret0
}

// NewQueryAsyncJobResultParams indicates an expected call of NewQueryAsyncJobResultParams.
func (mr *MockAsyncjobServiceIfaceMockRecorder) NewQueryAsyncJobResultParams(jobid interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewQueryAsyncJobResultParams", reflect.TypeOf((*MockAsyncjobServiceIface)(nil).NewQueryAsyncJobResultParams), jobid)
}

// QueryAsyncJobResult mocks base method.
func (m *MockAsyncjobServiceIface) QueryAsyncJobResult(p *QueryAsyncJobResultParams) (*QueryAsyncJobResultResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "QueryAsyncJobResult", p)
	ret0, _ := ret[0].(*QueryAsyncJobResultResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// QueryAsyncJobResult indicates an expected call of QueryAsyncJobResult.
func (mr *MockAsyncjobServiceIfaceMockRecorder) QueryAsyncJobResult(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryAsyncJobResult", reflect.TypeOf((*MockAsyncjobServiceIface)(nil).QueryAsyncJobResult), p)
}
