I'm deploying a simple class+test from sandbox to production. The test is successful on test but fails on deploy as stated on the title. I've checked validation rules, process builder flows and workflows or filters. Didn't detected a diff between both environments there. The error it's on this line :
System.AssertException: Assertion Failed: Expected: 1, Actual: 0 Stack Trace: Class.SchedulableCheckContractsTest.itShould: line 32, column 1
On this line :
System.assertEquals(1,[SELECT COUNT() FROM Invoice__c]);
Just to provide a bit of context we have a Process that creates a contract when an opportunity reaches 'Subscription Booked' StageName and this is both activated and identical on sandbox and prod.
Now what i'm deploying is a Schedulable+Batchable class that checks all contracts and creates an invoice if the month corresponds with an invoice month.
Apex Class (deleted debug statements and post insert mailing functionalities to save space)
global class SchedulableCheckContracts implements Database.Batchable<sObject>,Schedulable {
global void execute(SchedulableContext sc) {
Database.executeBatch(new SchedulableCheckContracts());
}
public Iterable<sObject> start(Database.Batchablecontext BC){
Map<id,Contract> MapContracts = new Map<id,Contract> ([SELECT id,Amount_invoice__c,Accountid,EndDate,StartDate,Billing_Agreement_Months__c,ContractTerm FROM Contract WHERE EndDate > Today]);
for(Contract currentContract: MapContracts.values()) {
if(!isInvoiceTime(currentContract)) MapContracts.remove(currentContract.id);
}
return new List<Contract> (MapContracts.values());
}
public void execute(Database.BatchableContext BC, List<sObject> scope){
List <Invoice__c> invoiceToInsert = new List <Invoice__c> ();
for(Contract currentContract: (List <Contract>) scope) {
invoiceToInsert.add(new Invoice__c(Date_Invoice__c = System.today(),
Contract__c = currentContract.id,
Account__c = currentContract.Accountid,
Type__c = 'Subscription Invoice',
Amount__c = currentContract.Amount_invoice__c)); // TODO declare invoice fields
}
Database.SaveResult[] srList = Database.insert(invoiceToInsert,false);
}
public void finish(Database.BatchableContext info){
}
// This function receives a contract and based on the current day, determines if we have to generate an invoice for the current month.
public Boolean isInvoiceTime(Contract C){
return Math.mod(Math.abs(C.startDate.month()-System.today().month()),(Integer)C.Billing_Agreement_Months__c) == 0;
}
}
Apex Test Class
@isTest
private class SchedulableCheckContractsTest
{
static void test1()
{
TestDataFactory.insertGeckoboardSettings();
TestDataFactory.insertOutboundMessageSettings();
Account a = TestDataFactory.createAccount('a');
A.Account_Status__c = 'Approved';
insert a;
Opportunity O = new Opportunity(Effective_Date__c = System.today().addDays(-1),CloseDate = System.today(),Accountid = a.id,Amount = 100000, Name='test A',StageName='Stage 3: Business Discovery',Type='Spot');
insert O;
O.StageName = 'Subscription Booked';
O.Fee__c = 0.29;
O.Contract_term__c = '12';
O.Billing_Agreement__c = 'Monthly';
O.Monthly_FX_Service_Package_Fee__c = 500;
O.Monthly_Subscription_Revenue__c = 500;
O.Subscription_Package__c = 'SW Subscription - Enterprise';
update O;
System.assertequals(1,[SELECT COUNT() FROM Contract]);
Contract C = [SELECT id,endDate FROM Contract LIMIT 1];
C.EndDate = System.today().addMonths(1);
update C;
Test.startTest();
SchedulableCheckContracts SCC = new SchedulableCheckContracts();
Database.executeBatch(SCC);
Test.stopTest();
System.assertEquals(1,[SELECT COUNT() FROM Invoice__c]);
}
}
After all the morning trying to find out what the diffs are between both environments which is the only reason I think to explain why this is happening I found no match yet and would like to know what are the most probable things that are causing this Assertion to fail or if there's something i'm missing. Any criticism related to the code is always welcome too.
Database.SaveResult[] srList = Database.insert(invoiceToInsert,false);
and see if record get inserted because if you get any error then it will not create record.