0

I have created the test class for the zenkraft process, but when I run this test class it stops the code coverage after the following line

i.e batchId = zkusps.BulkShipmentInterface.validateBulkShipment(bulkShipmentId);

and it shows the following error message i.e
System.AsyncException: Database.executeBatch cannot be called from a batch start, batch execute, or future method.

Is there any mock class for this test class.Please help me

My apex class:

global class MakeShipmentQueue implements Database.Batchable{

private Id bulkShipmentId;
private String batchId;      
public final String workingObject = 'ChargentOrders__ChargentOrder__c';
global String scope;

global Database.QueryLocator start(Database.BatchableContext BC) {

    String orderStatus = 'Initiated';
    return Database.getQueryLocator([SELECT Id FROM ChargentOrders__ChargentOrder__c WHERE ChargentOrders__Status__c = :orderStatus]);
}

global void execute(Database.BatchableContext BC, List<ChargentOrders__ChargentOrder__c> scope) {

    if(scope.size() > 0){

        List<zkusps__ShippingPreference__c> caseShipmateList = [SELECT zkusps__CompanyName__c, zkusps__ShippingCity__c, zkusps__preference__c, zkusps__shippingSenderEmailDefault__c,
                                                                zkusps__shippingSenderPhoneDefault__c, zkusps__ShippingState__c, zkusps__ShippingStreet__c, 
                                                                zkusps__ShippingPostalCode__c, zkusps__LabelImageTypeDefault__c FROM zkusps__ShippingPreference__c LIMIT 1];


        if ( ! caseShipmateList.isEmpty() ) {

            // 1. zkusps__BulkShipment__c object
            zkusps__BulkShipment__c bulkShipment = new zkusps__BulkShipment__c (
                zkusps__BillingPreference__c = caseShipmateList.get(0).zkusps__preference__c
            );
            insert bulkShipment;
            bulkShipmentId = bulkShipment.Id;

            List<zkusps__CustomAddressSource__c> customAddressSourceList = [SELECT Id FROM zkusps__CustomAddressSource__c WHERE zkusps__CustomAddressSourceObject__c = 
                                                                            :workingObject LIMIT 1];


            Set<Id> orderIds = new Set<Id>();
            for(ChargentOrders__ChargentOrder__c order : scope) {
                orderIds.add(order.Id);
            }

            /* Get all unshiped Orders */
            List<ChargentOrders__ChargentOrder__c> orders = [ SELECT ChargentOrders__Shipping_City__c, ChargentOrders__Shipping_Country__c, ChargentOrders__Billing_Email__c, 
                                                                ChargentOrders__Billing_First_Name__c, ChargentOrders__Billing_Last_Name__c, ChargentOrders__Billing_Phone__c, 
                                                                ChargentOrders__Shipping_State__c, ChargentOrders__Shipping_Address__c, ChargentOrders__Shipping_Zip_Postal__c 
                                                                FROM ChargentOrders__ChargentOrder__c WHERE Id IN : orderIds];



            if ( ! customAddressSourceList.isEmpty() ) {

                // 2. zkusps__QueuedShipment__c object
                zkusps__QueuedShipment__c[] queueItems = new zkusps__QueuedShipment__c[]{};

                    for(ChargentOrders__ChargentOrder__c order : orders){

                        zkusps__QueuedShipment__c queuedShipment = new zkusps__QueuedShipment__c (
                            zkusps__BulkShipment__c = bulkShipment.Id,
                            zkusps__LabelImageType__c = caseShipmateList.get(0).zkusps__LabelImageTypeDefault__c,
                            zkusps__ServiceType__c = 'Domestic: Express',
                            zkusps__PackagingType__c = 'Parcel',   

                            // sender info
                            zkusps__SenderName__c = caseShipmateList.get(0).zkusps__CompanyName__c,
                            zkusps__SenderCity__c = caseShipmateList.get(0).zkusps__ShippingCity__c,
                            zkusps__SenderCompany__c = caseShipmateList.get(0).zkusps__CompanyName__c,
                            zkusps__SenderEmail__c = caseShipmateList.get(0).zkusps__shippingSenderEmailDefault__c,
                            zkusps__SenderPhone__c = caseShipmateList.get(0).zkusps__shippingSenderPhoneDefault__c,
                            zkusps__SenderState__c = caseShipmateList.get(0).zkusps__ShippingState__c,
                            zkusps__SenderStreet__c = caseShipmateList.get(0).zkusps__ShippingStreet__c,
                            zkusps__SenderPostalCode__c = caseShipmateList.get(0).zkusps__ShippingPostalCode__c,

                            // recipient info 
                            zkusps__RecipientCity__c = order.ChargentOrders__Shipping_City__c,
                            zkusps__RecipientCompany__c = '',
                            zkusps__RecipientCountry__c = 'US',
                            zkusps__RecipientEmail__c = order.ChargentOrders__Billing_Email__c,
                            zkusps__RecipientName__c = order.ChargentOrders__Billing_First_Name__c,
                            zkusps__RecipientPhone__c = order.ChargentOrders__Billing_Phone__c,
                            zkusps__RecipientState__c = order.ChargentOrders__Shipping_State__c,
                            zkusps__RecipientStreet__c = order.ChargentOrders__Shipping_Address__c,
                            zkusps__RecipientPostalCode__c = order.ChargentOrders__Shipping_Zip_Postal__c,
                            zkusps__CustomAddressSource__c = customAddressSourceList.get(0).id,
                            zkusps__CustomAddressSourceRecordId__c = order.Id);

                        queueItems.add(queuedShipment);                                        
                    }
                    insert queueItems;

                List<zkusps__QueuedShipment__c> queuedShipmentIds = [SELECT Id FROM zkusps__QueuedShipment__c WHERE zkusps__CustomAddressSourceRecordId__c IN : orderIds];

                // 3. zkusps__QueuedPackage__c object
                zkusps__QueuedPackage__c[] queuedPackages = new zkusps__QueuedPackage__c[]{};
                for(zkusps__QueuedShipment__c queueId : queuedShipmentIds){

                    zkusps__QueuedPackage__c queuedPackage = new zkusps__QueuedPackage__c (
                        zkusps__DeclaredValue__c = 0,
                        zkusps__WeightPounds__c = 0,
                        zkusps__QueuedShipment__c = queueId.Id          
                    );
                    queuedPackages.add(queuedPackage);
                }
                insert queuedPackages;    

                // Validate shipping address 
                batchId = zkusps.BulkShipmentInterface.validateBulkShipment(bulkShipmentId);

                zkusps__BulkShipmentStatus__c statuses = new zkusps__BulkShipmentStatus__c();

                statuses.zkusps__BulkShipment__c = bulkShipmentId;
                statuses.zkusps__Status__c = 'VALIDATION_COMPLETED';
                insert statuses;

                batchId = zkusps.BulkShipmentInterface.processBulkShipment(bulkShipmentId); 

            }else {

                System.debug('Invalid Custom Address Source.');
                return;  
            }   
        }else {

            System.debug('Invalid Preference.');
            return;
        } 

    } else{

        System.debug('0 order found with status "Initiated"');
        return;
    }        
}

global void finish(Database.BatchableContext BC) {

}

}

Its Test class is:

@isTest public class MakeShipmentQueueTest {

@testsetup
/* For data test */
static void testData() {

    /* Order info */
    ChargentOrders__ChargentOrder__c chargeOrder = new ChargentOrders__ChargentOrder__c();
    chargeOrder.ChargentOrders__Status__c = 'Initiated';
    chargeOrder.ChargentOrders__Shipping_City__c = 'Chicago';
    chargeOrder.ChargentOrders__Shipping_Country__c = 'United States';
    chargeOrder.ChargentOrders__Billing_Email__c = '[email protected]';
    chargeOrder.ChargentOrders__Billing_First_Name__c = 'Erin';
    chargeOrder.ChargentOrders__Billing_Last_Name__c = 'Lang';
    chargeOrder.ChargentOrders__Billing_Phone__c = '(312) 813-9876';
    chargeOrder.ChargentOrders__Shipping_State__c = 'IL';
    chargeOrder.ChargentOrders__Shipping_Address__c = '1050 Marshfield Ave #3';
    chargeOrder.ChargentOrders__Shipping_Zip_Postal__c = '60622';
    insert chargeOrder;

    /* zenkraft preference info */
    zkusps__Preference__c testbillingzkusps = new zkusps__Preference__c();
    testbillingzkusps.zkusps__accountContactEmail__c ='[email protected]';
    testbillingzkusps.zkusps__accountContactName__c ='Mcnabb SalesforceAdmin';
    insert testbillingzkusps;

    /* zenkraft shipping preference info*/
    zkusps__ShippingPreference__c testzkusps = new zkusps__ShippingPreference__c();
    testzkusps.zkusps__CompanyName__c = 'McNabb Technologies LLC';
    testzkusps.zkusps__ShippingCity__c = 'Chicago';
    testzkusps.zkusps__preference__c = testbillingzkusps.Id;
    testzkusps.zkusps__shippingSenderEmailDefault__c = '[email protected]';
    testzkusps.zkusps__shippingSenderPhoneDefault__c = '3109785333';
    testzkusps.zkusps__ShippingState__c = 'IL';
    testzkusps.zkusps__ShippingStreet__c = '1621 W Walnut St';
    testzkusps.zkusps__ShippingPostalCode__c = '60612';
    testzkusps.zkusps__LabelImageTypeDefault__c = 'ZPLII';
    insert testzkusps;

    /* zenkraft bulkshipment info */
    zkusps__BulkShipment__c testbulkShipment = new zkusps__BulkShipment__c ();
    testbulkShipment.zkusps__BillingPreference__c = testbillingzkusps.Id;
    insert testbulkShipment;

    /* zenkraft custom address source info */
    zkusps__CustomAddressSource__c testcustomadd = new zkusps__CustomAddressSource__c();
    testcustomadd.zkusps__CustomAddressSourceObject__c = 'ChargentOrders__ChargentOrder__c';
    insert testcustomadd;

    /* zenkraft queued shipment info */
    zkusps__QueuedShipment__c testqueuedship = new zkusps__QueuedShipment__c();
    testqueuedship.zkusps__BulkShipment__c =testbulkShipment.Id;
    testqueuedship.zkusps__LabelImageType__c =testzkusps.zkusps__labelImageTypeDefault__c;
    testqueuedship.zkusps__ServiceType__c ='Domestic: Express';
    testqueuedship.zkusps__PackagingType__c ='Parcel';
    // sender info
    testqueuedship.zkusps__SenderName__c = testzkusps.zkusps__CompanyName__c;
    testqueuedship.zkusps__SenderCity__c = testzkusps.zkusps__ShippingCity__c;
    testqueuedship.zkusps__SenderCompany__c = testzkusps.zkusps__CompanyName__c;
    testqueuedship.zkusps__SenderEmail__c = testzkusps.zkusps__shippingSenderEmailDefault__c;
    testqueuedship.zkusps__SenderPhone__c = testzkusps.zkusps__shippingSenderPhoneDefault__c;
    testqueuedship.zkusps__SenderState__c = testzkusps.zkusps__ShippingState__c;
    testqueuedship.zkusps__SenderStreet__c = testzkusps.zkusps__ShippingStreet__c;
    testqueuedship.zkusps__SenderPostalCode__c = testzkusps.zkusps__ShippingPostalCode__c;
    // recipient info
    testqueuedship.zkusps__RecipientCity__c = chargeOrder.ChargentOrders__Shipping_City__c;
    testqueuedship.zkusps__RecipientCompany__c = '';
    testqueuedship.zkusps__RecipientCountry__c = 'US';
    testqueuedship.zkusps__RecipientEmail__c = chargeOrder.ChargentOrders__Billing_Email__c;
    testqueuedship.zkusps__RecipientName__c = chargeOrder.ChargentOrders__Billing_First_Name__c;
    testqueuedship.zkusps__RecipientPhone__c = chargeOrder.ChargentOrders__Billing_Phone__c;
    testqueuedship.zkusps__RecipientState__c = chargeOrder.ChargentOrders__Shipping_State__c;
    testqueuedship.zkusps__RecipientStreet__c = chargeOrder.ChargentOrders__Shipping_Address__c;
    testqueuedship.zkusps__RecipientPostalCode__c = chargeOrder.ChargentOrders__Shipping_Zip_Postal__c;
    testqueuedship.zkusps__CustomAddressSource__c = testcustomadd.id;
    testqueuedship.zkusps__CustomAddressSourceRecordId__c = chargeOrder.Id;
    insert testqueuedship;

    /* zenkraft queued package info */
    zkusps__QueuedPackage__c testqueuedpack = new zkusps__QueuedPackage__c();
    testqueuedpack.zkusps__DeclaredValue__c = 0;
    testqueuedpack.zkusps__WeightPounds__c = 0;
    testqueuedpack.zkusps__QueuedShipment__c = testqueuedship.Id;
    insert testqueuedpack;

    /* zenkraft bulk shipment status info */
    zkusps__BulkShipmentStatus__c testbulkship = new zkusps__BulkShipmentStatus__c();
    testbulkship.zkusps__BulkShipment__c = testbulkShipment.Id;
    testbulkship.zkusps__Status__c = 'VALIDATION_COMPLETED';
    insert testbulkship;

}

/* For Scheduler test */
static testMethod void testScheduler() {
    System.schedule('Test Checker', '0 0 0/1 1/1 * ? *', new ZenKraftBatchScheduler());
}

/* For Batch test */
static testMethod void testBatch() {
    MakeShipmentQueue objBatch = new MakeShipmentQueue();
    Database.executeBatch(objBatch);
}

}

1

2 Answers 2

0

It sounds like the call that you are making from the execute method of a batchable is causing another batchable to execute and as the message explains that is not supported. I would expect the same error to occur when the code is used in a non-test context i.e. the test is exposing a design problem that needs fixing. But worth confirming the problem in the non-test context first.

A simple fix would be to find an equivalent method to zkusps.BulkShipmentInterface.validateBulkShipment that runs synchronously: you will need to check the set of methods available and may need to contact the package supplier.

If no such method is available then you have a bigger problem in that you will need to seek out a design using some combination of batchable/queuable/future/synchronous code that avoids this nested batchable problem. Or are you sure you need your batchable?

PS

I see there is some documentation such as USPS Bulk Shipping Platform Developer Guide that suggests the API is largely asynchronous. Probably best if you contact their support and discuss your needs - they may be able to suggest an API or pattern that will meet them.

0

You will need to use our sync methods.

BulkShipmentInterface.validateBulkShipment(bulkShipmentId) 

and

BulkShipmentInterface.processBulkShipment(bulkShipmentId) 

are async methods.

We have sync methods that you can use:

BulkShipmentInterface.validateBulkShipmentSynchronous(bulkShipmentId) 

and

BulkShipmentInterface.processBulkShipmentSynchronous(bulkShipmentId) 

You should use Test.startTest() and Test.stopTest() around the Database.executeBatch(objBatch) in Test class.

For example:

Test.startTest();
Database.executeBatch(objBatch);
Test.stopTest();

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .