[SalesForce] Creating Holidays and Business Hours in Test Code

I have been creating a Business Hours Calculation engine in the past few weeks and have gotten some great help on a few questions I've already asked (BH in Apex, BH and Holiday Affiliation).

I have my code working exaclty how I want it and now have moved on to test code. As Bob Buzzard Pointed out, although it's not well documented, Business Hour Data as well as Holidays are available in Test Code Context.

@isTest
private class BusinessHoursMathTest {

    static testmethod void SimpleTest(){

        List<BusinessHours> bhs = [select id from BusinessHours where IsDefault=true];
        System.assert(bhs.size() == 1);

        List<Holiday> holidays = [Select Id From Holiday];
        system.assert(!holidays.isEmpty());

        List<Account> accs = [select id from Account];
        System.assert(accs.isEmpty());
    }   
}

The issue is there is no connection between the two. I cannot tell if a Holiday I query for is affiliated with a set of Business Hours. Ideally, in a perfect world I would be able to create a set of business hours, insert them, create a holiday, affiliated with those business hours and insert it. Easy, except DML is not allowed on business hours. I can insert holidays, but there is no way to affiliate it with the Business Hours I have queried for.

So I would think that it would be as simple as Querying for Default business Hours, creating a new Holiday, and associating that Holiday with the Business Hours. Something like this

BusinessHours defaultBH = [Select Id From BusinessHours Where IsDefault = True];
Holiday hol = new Holiday();
hol.Name='Test holiday';
hol.activitydate = System.Today();
insert hol;

The holiday is inserted, but there is no affiliation of that Holiday with the Business Hours. I have found that there is no way to affiliate the Holiday with the business hours with Apex. There are 2 major problems here.

  1. I am 100% reliant on existing business hours in the org if I cannot
    create or update Business Hours. This goes against all testing best
    practices I know. Makes it close to impossible to properly test my
    code with assertions.
  2. Even though I can create holidays, the fact
    that I can't affiliate them with business hours makes it fairly
    useless.

There was already an Idea on the Idea exchange around exposing the affiliation between Holidays and Business Hours in Apex seen here. I also created an Idea asking to allow DML on Business Hours seen here

MY QUESTION

Does anyone know of a workaround for this. How can I properly test business hour logic without being able to create holidays or create/edit Business Hours in the test class.

As it is now I am 100% reliant on existing data in the org to test my business hour calculations, which prevents me from fully testing all possibilities and edge cases.

Has anyone come up with a way to do this or can you let me know if I have missed anything or not going about this the proper way. I'm pulling my hair out with this one.

Best Answer

I was a bit curious and I actually verified what you said

Business Hour Data is available in Test Code Context. Holidays, however are not, you have to create your own.

Are you sure about that? Because it returns my holiday. I made my test on api 28.0 and 29.0

I've created one Holiday and run exactly the same test.

@isTest
private class TestBusinessHours {

    @isTest static void test_method_one() {
        List <BusinessHours> records = [select id from BusinessHours where isDefault = true];
        System.assert(records.size() == 1);

        List <Holiday> holidays = [Select Id From Holiday];
        System.assert(holidays.size() == 0);
    }
}

Here is my result:

14:22:30.554 (1554897000)|SOQL_EXECUTE_BEGIN|[5]|Aggregations:0|select id from BusinessHours where isDefault = true
14:22:30.573 (1573725000)|SOQL_EXECUTE_END|[5]|Rows:1
14:22:30.574 (1574225000)|SOQL_EXECUTE_BEGIN|[8]|Aggregations:0|select Id from Holiday
14:22:30.575 (1575604000)|SOQL_EXECUTE_END|[8]|Rows:1
14:22:30.575 (1575763000)|EXCEPTION_THROWN|[9]|System.AssertException: Assertion Failed
14:22:30.575 (1575909000)|FATAL_ERROR|System.AssertException: Assertion Failed

Class.TestBusinessHours.test_method_one: line 9, column 1
14:22:30.575 (1575927000)|FATAL_ERROR|System.AssertException: Assertion Failed

Class.TestBusinessHours.test_method_one: line 9, column 1

Maybe add @isTest in your SimpleTest Mehtod ;-)

Related Topic