Tuesday, April 26, 2011

Apex Static Resource

StaticResources can be used in unit tests to store data that would otherwise clutter the test cases.

StaticResource xml = [select body, name from StaticResource where name = 'StaticResourceName'  limit 1];

Thursday, April 21, 2011

Salesforce Apex Test class and callouts

The Test.isRunningTest() method is a useful method to bypass web service callouts when running automated test cases that would otherwise fail.

For example, in any wsdl2apex generated classes find the WebServiceCallout.invoke() method calls and then wrap them in an test for Test.isRunningTest(). If the test is false the code can still call invoke as generated. Otherwise the code can simulate the web service response, allowing the test cases to complete.

Monday, April 4, 2011

MSBuild - sort an ItemGroup

An automated MSBuild script that creates a database from scratch started failing after switching from vcvarall.bat provided by a Visual Studio 2008 install to the Visual Studio 2010 version.

For some unknown reason, the order of files listed in a ItemGroup was reversed. With files beginning with an underscore running last rather than first.

The issue was resolved by explicitly sorting the ItemGroup using a custom task from the MSBuild Extension Pack.


    <!-- Have a fallback check depending on path locally or on build server -->
    <PropertyGroup>
        <TPath>$(MSBuildProjectDirectory)\ExtensionPack\MSBuild.ExtensionPack.tasks</TPath>
        <TPath Condition="Exists('C:\Program Files (x86)\MSBuild\ExtensionPack\MSBuild.ExtensionPack.tasks')">C:\Program Files (x86)\MSBuild\ExtensionPack\MSBuild.ExtensionPack.tasks</TPath>
    </PropertyGroup>
    <Import Project="$(TPath)"/>

    <!-- ... -->

    <Target Name="MainData">
        <Message Text="Inserting Data Main (Main Data)" />

        <!-- Sort an ItemGroup alphabetically -->
        <MSBuild.ExtensionPack.Framework.MsBuildHelper TaskAction="Sort" InputItems1="@(MainDataFiles)">
            <Output TaskParameter="OutputItems" ItemName="sorted"/>
        </MSBuild.ExtensionPack.Framework.MsBuildHelper>
        <Message Text="Sorted Items: %(sorted.Identity)"/>
    
        <Exec Command="$(SqlCmdPrefix) -i %(sorted.Identity)" />
    </Target>


See Also:

Tuesday, March 29, 2011

Modifying TFS build server output to seperate project outputpaths

By default a TFS build server outputs all projects in a solution, with the exception of web applications, into a single directory.

To separate the build output directoyr import a modified version of Microsoft.WebApplication.targets into the applicable csproj files.

<Import Project="Modified.Microsoft.WebApplication.targets" />

See also:

Friday, March 25, 2011

APEX String.format(); Syntax - escaping single quotes

The Apex String method format() is my preferred way to build up a string in the absence of something like a .NET StringBuilder.

The help docs are currently a bit lightweight on detail:

Treat the current string as a pattern that should be used for substitution in the same manner as apex:outputText.

The apex:outputText documentation says:

The value attribute supports the same syntax as the MessageFormat class in Java. See the MessageFormat class JavaDocs for more information.

The syntax in Eclipse appears as: String.format(String pString, List pLIST:String) String

Usage is a format string followed by the substitution arguments as an array.

String formattedString = String.format('Hello {0}, shall we play a {1}?', new String[]{'David', 'game'});
System.debug(formattedString);

Apex String.format and escaped single quotes

String.format(); can be a bit fiddly when it comes to outputting single quotes. A solitary escaped single quote will be lost from the output and prevent further string substitutions.

For Example:

String formattedString = String.format('Hello {0}, shall we play a \'{1}\'?', new String[]{'David', 'game'});
System.debug(formattedString);

Will result in:

Hello David, shall we play a {1}?

The java.text.MessageFormat documentation says:

Within a String, "''" represents a single quote. A QuotedString can contain arbitrary characters except single quotes; the surrounding single quotes are removed.

Example with the escaping to produce the expected output:

String formattedString = String.format('Hello {0}, shall we play a \'\'{1}\'\'?', new String[]{'David', 'game'});  
System.debug(formattedString); 

Will result in:

Hello David, shall we play a 'game'?

See Also:

Thursday, March 10, 2011

Find the length of a Salesforce field in Apex

Usually through the Partner API I can use describeSObject() to determine the maximum allowed length of a field.

To do this in Apex use the following - changing CustObj__c and CustField__c as required:

integer fieldLength = Schema.SObjectType.CustObj__c.fields.CustField__c.getLength();

See Also:

Comparing APEX Datetime instances

Something odd is happening with Datetime values in APEX automated tests.

At the start of an automated test case the current date and time is captured using:

  DateTime testStart = DateTime.now();

Then after a number of operations an Account is created. The automated test checks that the CreatedDate of the new Account (after insertion) is greater than when the automated test started.

System.assert(account.CreatedDate > testStart, 'New Account expected - Created Date['+account.CreatedDate+'] <= testStart date['+testStart+'].');

This test assertion fails with the CreatedDate and testStart having exactly the same value according to the assert message.

Converting the Datetimes to longs shows the testStart has more precision than the CreatedDate. It would appear that DateTimes stored in the database lose the millisecond precision.

System.assert(account.CreatedDate.getTime() > testStart.getTime(), 'New Account expected - Created Date['+account.CreatedDate.getTime()+'] < testStart date['+testStart.getTime()+'].');