18

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.

  • What about wrapper classes that provide the BH-Holiday relationship data? Such wrapper classes execute differently in PROD (use SOQL to fetch relationships) vs test (use test maps to simulate the relationships). That is, abstract the BH-Holidays relationships to classes/methods. – cropredy May 6 '14 at 18:02
  • The issue is you can't fetch the relationships in Prod either. there is no way to fetch a relationship between Business Hours and Production. In my class I have to use the Business Hours method isWithin(), as this respects holidays associated with the business hours. With no way to fetch relationships, I can't abstract it out into a wrapper class that I can see. There seems to be a major bug in the system that prevents us access to the BH -> holiday relationship in Apex, unless I am missing it somewhere. – Chris Duncombe May 6 '14 at 18:05
2
+50

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 ;-)

  • 1
    That was a mistake on my part, you can query for holidays and I have updated my question to reflect this. Thank you, but the main issue still remains. I am reliant on existing data, and there is no way to link holidays with business hours, making proper testing nearly impossible. – Chris Duncombe May 9 '14 at 12:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.