function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Martha VMartha V 

advanced apex superbadge step 5 - Ensure that you create the OrderUpdate_UnitTest test method with the proper declaration and proper access modifier, to ensure best practices.

I am stuck in this step. My tests are running and I have 100% coverage, but there is something Trailhead is not liking. Do you know what can it be?

Here is my OrderTests class:
@IsTest
private class OrderTests {
    
	   
    @testSetup static void SetupTestData(){
        TestDataFactory.InsertTestData(5);
    }

    
    @isTest static void OrderUpdate_UnitTest(){
        //retrieve the orders saved by TestDataFactory
        Map<Id, Order> orders= new Map<Id, Order>([SELECT Id, Status FROM Order]);
        //save the original Product2 record in a map
        Map<Id, Product2> originalProductMap = new Map<Id, Product2>();
        //Loop through a query of OrderItems related to the orders
        List<OrderItem> items = [SELECT Id, Product2Id, Product2.Quantity_Ordered__c, Quantity
                                 FROM OrderItem
                                 WHERE OrderId IN :orders.keySet()];
        //ToDo: Populate the map with the Id of the related Product2 as the key and Product2 record as the value
        for ( OrderItem oi : items){
            Product2 p = oi.Product2;
            if (!originalProductMap.containsKey(p.Id)) {
                originalProductMap.put(p.Id, p);
            } 
        }
        //update the Status of the orders
        List<Order> updatedOrders = new List<Order>();
        for (Order order : orders.values()) {
            order.Status = Constants.ACTIVATED_ORDER_STATUS;
            updatedOrders.add(order);
        }
        //get the amounts to be order for each Product
        //declare a map to save the Amounts for each product
        Map<Id, Integer> prodAmounts = new Map<Id, Integer>();
        //get the aggregated amounts by product id
        AggregateResult[] groupedResults  = [SELECT Product2Id, SUM(Quantity) FROM OrderItem
                                             WHERE Product2Id IN :originalProductMap.keySet() 
                                             GROUP BY Product2Id];
        for (AggregateResult ar : groupedResults)  {
             prodAmounts.put(String.valueOf(ar.get('Product2Id')),Integer.valueOf(ar.get('expr0')));
        }                                     
        //update the orders in the DB
        update updatedOrders;
        //retrieve the products affected by the orders update
        Map<Id, Product2> updatedProductMap = new Map<Id, Product2>([SELECT id, Quantity_Ordered__c 
                                                                     FROM Product2 WHERE
                                                                     id IN :originalProductMap.keySet()]);
        for (Product2 origProd : originalProductMap.values()) {
            TestDataFactory.VerifyQuantityOrdered(origProd,updatedProductMap.get(origProd.Id), prodAmounts.get(origProd.Id));
        }
    }

}

and my TestDataFactory
 
/**
 * @name TestDataFactory
 * @description Contains methods to construct and/or validate commonly used records
**/
public with sharing class TestDataFactory {

    /**
     * @name ConstructCollaborationGroup
     * @description
    **/
    public static CollaborationGroup ConstructCollaborationGroup(){
        //ToDo: Ensure this method returns a single Chatter CollaborationGroup
        //    whose Name starts with 'TEST' followed by the INVENTORY_ANNOUNCEMENTS constant
        //    and configured so anyone can join, see and post updates.
        return (new CollaborationGroup(Name = 'TEST' + Constants.INVENTORY_ANNOUNCEMENTS,
                                       CollaborationType = 'Public'));        
    }

    /**
     * @name CreateProducts
     * @description Constructs a list of Product2 records for unit tests
    **/
    public static List<Product2> ConstructProducts(Integer cnt){
        for (Schema.PicklistEntry fam : Constants.PRODUCT_FAMILY){

        }
        //ToDo: Ensure this method returns a list, of size cnt, of uniquely named Product2 records
        //  with all the required fields populated
        //  and IsActive = true
        //  an Initial Inventory set to 10
        //  and iterating through the product family picklist values throughout the list.
        List<Product2> products = new List<Product2>();
        Integer i = 0;
        for (Integer x = 0; x < cnt; x++ ){
            if (i > Constants.PRODUCT_FAMILY.size() -1 ) i = 0;            
            Product2 p = new Product2(Name = 'product' + x,
                                      Initial_Inventory__c = 10,
                                      IsActive = true,
                                      Family = Constants.PRODUCT_FAMILY[i].getLabel());
            i++;                          
            products.add(p);
        }
        return products;
    }

    /**
     * @name CreatePricebookEntries
     * @description Constructs a list of PricebookEntry records for unit tests
    **/
    public static List<PricebookEntry> ConstructPricebookEntries(List<Product2> prods){

        //ToDo: Ensure this method returns a corresponding list of PricebookEntries records
        //  related to the provided Products
        //  with all the required fields populated
        //  and IsActive = true
        //  and belonging to the standard Pricebook
        List<PricebookEntry> pbentries = new List<PricebookEntry>();
        for (Product2 p : prods){
            PricebookEntry pb = new PricebookEntry(IsActive = true,
                                       UnitPrice = 10,
                                       Pricebook2Id = Constants.STANDARD_PRICEBOOK_ID,
                                       Product2Id = p.Id);
            pbentries.add(pb);                           
        }
        return pbentries;
    }

    /**
     * @name CreateAccounts
     * @description Constructs a list of Account records for unit tests
    **/
    public static List<Account> ConstructAccounts(Integer cnt){
        //ToDo: Ensure this method returns a list of size cnt of uniquely named Account records
        //  with all of the required fields populated.
        List<Account> accounts = new List<Account>();
        for (Integer x=0; x<cnt; x++) {
            Account acc = new Account(Name = 'account ' + x);
            accounts.add(acc);
        }
        return accounts;
    }

    /**
     * @name CreateContacts
     * @description Constructs a list of Contacxt records for unit tests
    **/
    public static List<Contact> ConstructContacts(Integer cnt, List<Account> accts){
        //ToDo: Ensure this method returns a list, of size cnt, of uniquely named Contact records
        //  related to the provided Accounts
        //  with all of the required fields populated.
        List<Contact> contacts = new List<Contact>();
        Integer y = 0;
        for (Integer x = 0; x < cnt; x++){
            if (y > accts.size() - 1) y = 0;
            Contact c = new Contact(FirstName = 'cont'+y,
                                    LastName = 'Last ' + y,
                                    AccountId = accts[y].Id );
            contacts.add(c);                        
            y++;
        }
        return contacts;
    }

    /**
     * @name CreateOrders
     * @description Constructs a list of Order records for unit tests
    **/
    public static List<Order> ConstructOrders(Integer cnt, List<Account> accts){
        //ToDo: Ensure this method returns a list of size cnt of uniquely named Order records
        //  related to the provided Accounts
        //  with all of the required fields populated.
        Integer y = 0;
        List<Order> orders = new List<Order>();
        for (Integer x = 0; x < cnt; x++) {
            if (! (y < accts.size())) y = 0;
            Order ord = new Order(AccountId = accts[y].Id,
                                  PriceBook2Id = Constants.STANDARD_PRICEBOOK_ID,
									Name = 'order '+ x,
                                    Status = Constants.DRAFT_ORDER_STATUS,
                                    EffectiveDate = date.today());
            orders.add(ord); 
            y++;               
        }
        return orders;
    }

    /**
     * @name CreateOrderItems
     * @description Constructs a list of OrderItem records for unit tests
    **/
    public static List<OrderItem> ConstructOrderItems(integer cnt, list<pricebookentry> pbes, list<order> ords){
        //ToDo: Ensure this method returns a list of size cnt of OrderItem records
        //  related to the provided Pricebook Entries
        //  and related to the provided Orders
        //  with all of the required fields populated.
        //  Hint: Use the DEFAULT_ROWS constant for Quantity as it will be used in the next challenge
        List<OrderItem> orditems = new List<OrderItem>();
        Integer y = 0;
        for (Integer x = 0; x < cnt; x++) {
            if (y > pbes.size() - 1) y = 0;
            OrderItem oi = new OrderItem(OrderId = ords[y].Id,
                                            PricebookEntryId = pbes[y].Id,
                                            Quantity = Constants.DEFAULT_ROWS,
                                            UnitPrice = 1);
            orditems.add(oi);
            y++;
        }
        return orditems;
    }

    /**
     * @name SetupTestData
     * @description Inserts accounts, contacts, Products, PricebookEntries, Orders, and OrderItems.
    **/
    public static void InsertTestData(Integer cnt){
        //ToDo: Ensure this method calls each of the construct methods
        //  and inserts the results for use as test data.
        CollaborationGroup cg = ConstructCollaborationGroup();
        insert cg;
        system.debug('inserted CollaborationGroup');
        List<Product2> prods = ConstructProducts(cnt);
        insert prods;
        system.debug('inserted products');
        List<PricebookEntry> pbes = ConstructPricebookEntries(prods);
        try {
            insert pbes;
            system.debug('inserted PriceBookEntries');
        } catch (Exception e) {
            system.debug('exception: ' + e.getMessage());
        }
        List<Account> accts = ConstructAccounts(cnt);
        insert accts;
        system.debug('inserted Accounts');
        List<Contact> conts = ConstructContacts(cnt, accts);
        insert conts;
        system.debug('inserted Contacts');
        List<Order> orders = ConstructOrders(cnt,accts);
        insert orders;
        system.debug('inserted orders');
        List<OrderItem> ordItems = ConstructOrderItems(cnt, pbes, orders);
        insert ordItems;
        system.debug('inserted OrderItems');
    }
    
    public static void VerifyQuantityOrdered(Product2 originalProduct, Product2 updatedProduct, Integer qtyOrdered) {
        system.debug('Original Product.quantity = ' + originalProduct.Quantity_Ordered__c);
        system.debug('qtyOrdered = '+ qtyOrdered);
        system.debug('updated product.quantity = ' + updatedProduct.Quantity_Ordered__c);
        
        system.assertEquals(qtyOrdered, updatedProduct.Quantity_Ordered__c - originalProduct.Quantity_Ordered__c );
    }

}

 
Best Answer chosen by Martha V
NagendraNagendra (Salesforce Developers) 
Hi Martha,

Sorry for this issue you are facing.

I faced a similar issue in the past and I was able to solve the problem by simply adding the signature of the two test methods for OrderExtension and product2Trigger in the OrderTest class.
@isTest
    private static void OrderExtension_UnitTest(){
        
    }

    @isTest
    public static void product2Trigger_UnitTest(){
        
    }
For more information please refer to below link. Hope this helps.

Kindly mark this as solved if the reply was helpful.

Thanks,
Nagendra
 

All Answers

NagendraNagendra (Salesforce Developers) 
Hi Martha,

Sorry for this issue you are facing.

I faced a similar issue in the past and I was able to solve the problem by simply adding the signature of the two test methods for OrderExtension and product2Trigger in the OrderTest class.
@isTest
    private static void OrderExtension_UnitTest(){
        
    }

    @isTest
    public static void product2Trigger_UnitTest(){
        
    }
For more information please refer to below link. Hope this helps.

Kindly mark this as solved if the reply was helpful.

Thanks,
Nagendra
 
This was selected as the best answer
Martha VMartha V
Thanks so much for your help Nagendra!  I finally passed it. I added the signatures of the methods as you suggested, but it still didn't pass. Then I just added the "private" in front of the class and the methods -including the ones you suggested - and that did the trick. I can't believe, it's been almost 2 weeks I've been stuck in this step... I wish trailhead had better testing methods. (no pun intended)