There are methods in AX to setup data before test execution and tear it down afterwards - SysTestCase.setup() and SysTestCase.tearDown(). Those methods will be executed before and after each test method in a unit test class.
In AX 2009 two new methods were added - setupTestCase() and tearDownTestCase() which are executed only once per unit test class execution - before first test method and after last test method. But there is a problem with using them - by default each unit test method runs in a separate instance of the unit test class, so if you are setting up some data in the setupTestCase() method there will be no possibility to store a reference to it in the instance variable.
To change this behavior useSingleInstance() method can be overridden to return true. In this case all test method as well as setupTestCase() and tearDownTestCase() method will be execute in one instance of the unit test class.
Showing posts with label AX 2009. Show all posts
Showing posts with label AX 2009. Show all posts
Friday, April 30, 2010
Monday, April 26, 2010
Switch statement and CLR enums
There is a really weird bug in AX 2009 with CLR enumerations. If the code has "if" statement that validates value of a variable of CLR enum type everything is fine. However, the same "switch" statement fails with kernel exception.
Example:
MyNamespace.MyEnum enum;
enum = MyNamespace.MyEnum::Value1;
if (enum == MyNamespace.MyEnum::Value1)
{
info("Everything is fine");
}
switch (enum)
{
case MyNamespace.MyEnum::Value1 :
info("And not so good here");
break;
}
Result:
Error executing code: Wrong argument types for comparison.
Example:
MyNamespace.MyEnum enum;
enum = MyNamespace.MyEnum::Value1;
if (enum == MyNamespace.MyEnum::Value1)
{
info("Everything is fine");
}
switch (enum)
{
case MyNamespace.MyEnum::Value1 :
info("And not so good here");
break;
}
Result:
Error executing code: Wrong argument types for comparison.
Wednesday, March 24, 2010
DefaultAction property on grids
DefaultAction property on the form grid control was added in AX 2009. It allows to specify a menu item from the form which will be executed on the double click event on the grid. Originally this feature targets list pages – it allows to open details forms for the selected record on the list page. However, it can be used for any grid on any form. The only limitation is that grid should not be editable.
Tuesday, March 23, 2010
Union queries
In AX 2009 a great enhancement was introduced to the queries – support for union operation was added. A new property was added to the AOT queries – QueryType. It has two values:
In the case of union query several datasources of the same type (the same table) can be placed on the query datasource root node. Note, that all datasources except the first one will have a property called UnionType, which specifies what should be done with duplicated records that may appear because of union:
Additional datasources can be added to the deeper levels of the query under any datasource that participates in union. Those will be translated into joins. The only allowed join types for the union query are exists and notexists join.
- Join – regular query
- Union – union query
In the case of union query several datasources of the same type (the same table) can be placed on the query datasource root node. Note, that all datasources except the first one will have a property called UnionType, which specifies what should be done with duplicated records that may appear because of union:
- Union – remove duplicated records
- UnionAll – keep duplicated records
Additional datasources can be added to the deeper levels of the query under any datasource that participates in union. Those will be translated into joins. The only allowed join types for the union query are exists and notexists join.

Tuesday, February 23, 2010
Caching edit methods
There was a great improvement done to the form datasource caching in AX 2009 - it is possible now to cache not only display methods but edit methods too. The caching of the edit methods can be performed in the same way as caching of display methods - by using FormDataSource.cacheAddMethod() method.
Despite that great improvement a lot of forms in AX 2009 haven't consumed it. So if you are looking for a solution to speed up existing AX 2009 form, edit methods that are not cached is a good place to look at.
Despite that great improvement a lot of forms in AX 2009 haven't consumed it. So if you are looking for a solution to speed up existing AX 2009 form, edit methods that are not cached is a good place to look at.
Thursday, February 18, 2010
SysQueryRangeUtil class
The SysQueryRangeUtil class is just the great enhancement to the AOT queries made in AX 2009. It is possible now to specify a range on the AOT query with the value taken from a method's return. The requirements for such range method are quite simple: the method should be static, return string, be a member of the SysQueryRangeUtil class and not be related on the data fetched by the query.

There are quite a lot of useful methods on the SysQueryRangeUtil class available out of the box, like currentEmployeeId() - returns current employee ID, dayRange() - allows to specify date interval around current date, etc. And it is possible to add a new custom method to this class as well.

There are quite a lot of useful methods on the SysQueryRangeUtil class available out of the box, like currentEmployeeId() - returns current employee ID, dayRange() - allows to specify date interval around current date, etc. And it is possible to add a new custom method to this class as well.
Monday, February 8, 2010
Conversion from UTCDateTime to Date or Time
One should be very careful with converting an UTCDateTime value to a Date and/or Time value or vice versa.
The problem is that values of type UTCDateTime are stored in the database in UTC time zone and in code they are accessible in UTC time zone too. But in the UI UTCDateTime values are displayed in user preferred time zone in most cases. Date and Time values are not related to any time zone, so in fact both stored and displayed values are equal.
Because of that each field or variable of type Date or Time should be strictly associated with some fixed time zone (in most cases it makes sense to associate it with user preferred time zone because it’s what user see in the UI) and explicit conversion should always be performed during assignments or comparisons. There are special methods in DateTimeUtil class to switch time zones.
Here is an example of correct conversion between UTCDateTime value and Date and Time value which is associated with user preferred time zone:
public static void testDateTimeConversion()
{
utcDateTime dateTime;
date dateInUserTimeZone;
TimeOfDay timeInUserTimeZone;
dateTime = DateTimeUtil::utcNow();
dateInUserTimeZone = DateTimeUtil::date(DateTimeUtil::applyTimeZoneOffset(dateTime, DateTimeUtil::getUserPreferredTimeZone()));
timeInUserTimeZone = DateTimeUtil::time(DateTimeUtil::applyTimeZoneOffset(dateTime, DateTimeUtil::getUserPreferredTimeZone()));
dateTime = DateTimeUtil::newDateTime(dateInUserTimeZone, timeInUserTimeZone, DateTimeUtil::getUserPreferredTimeZone());
}
The problem is that values of type UTCDateTime are stored in the database in UTC time zone and in code they are accessible in UTC time zone too. But in the UI UTCDateTime values are displayed in user preferred time zone in most cases. Date and Time values are not related to any time zone, so in fact both stored and displayed values are equal.
Because of that each field or variable of type Date or Time should be strictly associated with some fixed time zone (in most cases it makes sense to associate it with user preferred time zone because it’s what user see in the UI) and explicit conversion should always be performed during assignments or comparisons. There are special methods in DateTimeUtil class to switch time zones.
Here is an example of correct conversion between UTCDateTime value and Date and Time value which is associated with user preferred time zone:
public static void testDateTimeConversion()
{
utcDateTime dateTime;
date dateInUserTimeZone;
TimeOfDay timeInUserTimeZone;
dateTime = DateTimeUtil::utcNow();
dateInUserTimeZone = DateTimeUtil::date(DateTimeUtil::applyTimeZoneOffset(dateTime, DateTimeUtil::getUserPreferredTimeZone()));
timeInUserTimeZone = DateTimeUtil::time(DateTimeUtil::applyTimeZoneOffset(dateTime, DateTimeUtil::getUserPreferredTimeZone()));
dateTime = DateTimeUtil::newDateTime(dateInUserTimeZone, timeInUserTimeZone, DateTimeUtil::getUserPreferredTimeZone());
}
Tuesday, February 2, 2010
FormButtonManager
In AX 2009 a new nice framework was introduced to simplify form buttons enabling\disabling. This framework is primarily used for list pages, however it can be used for regular forms too. Usage of this framework is quite simple. A new class should be created for a form which implements ButtonStateProvider interface. This class will contain methods which define buttons enable\disable rules. After that form buttons should be mapped to the rules using FormButtonManager class. That's pretty much it. The only thing left is to call FormButtonManager.refresh() method on selection changed event to get buttons enabled or disabled according to specified rules.
For more details you can look at SMAAgreementTableListPage and SMAAgreementTableButtonStateProvider class.
For more details you can look at SMAAgreementTableListPage and SMAAgreementTableButtonStateProvider class.
Friday, January 29, 2010
FormDataSource.markChanged method
In AX 2009 a new method was added to the FormDataSource – markChanged() which is dedicated specifically to handle selection change event. Before that active() method was commonly used for this purpose, however it is not precise and there are cases when selection is changed but active() method is not triggered. It is the most important to use markChanged() instead of active() when multiple records selection needs to be handled.
Monday, January 11, 2010
Hiding content pane in AX 2009
A small trick can be done to hide content pane in AX 2009. Any list page should be opened and then content page can be hidden by pressing Ctrl-Q.
Subscribe to:
Posts (Atom)