Saturday, October 19, 2013

Learn UnitTest in .Net

You want to write unit test for any class. Following are the attributes you need to write a unit test.

Mandatory:
1 - TestClass - This attribute identifies that attributed class is a test class.
2 - TestMethod - This attribute identifies that the attributed method is a test method in the test class.

3 - TestInitialize: This attributed method runs before the every test method.
4 - TestCleanup: This attributed method runs after the every test method.
5 - ClassInitialize: This attributed method runs once when the unit test class is initialized. Normally it can be used when we perform DB seeding or mocking objects globally.
6 - ClassCleanup: This attributed method runs once when the unit test class has run all the test methods. It can be used when the data inserted needs to be rollback.
7 - TestCategory: When the group of classes need to executed simultaneously or in a one go then on the class this attributed is binded with any name. e.g. Financials or something else.
How to group module unit test classes.
8 -ExpectedException: When any function raise any exception then this attribute can be used.

Here's a snippet of a code that will show the above attributes.

//A business class that performs add operation.
public class Maths
   {
      public int Add(int a, int b)
      {
         return checked(a + b);
      }
   }


// A test class that checks the functionality of the business class Maths.
   [TestClass]
   public class UnitTest1
   {
      Maths obj = new Maths();
      
      [TestInitialize] // you can use ClassInitialize attribute. 
      public void Setup()
      {
         System.Diagnostics.Debug.WriteLine("In a child debug ");
      }

      [TestCleanup] // you can use ClassCleanup attribute.
      public void Cleanup()
      {
             obj.Dispose();
      }
//// A test method.
      [TestMethod]
      public void TestMethod12()
      {
         Assert.IsTrue(obj.Add(2, 3) == 5);  
      }
/// A test method that shows exception checking.
      [TestMethod]
      [ExpectedException(typeof(OverflowException))]
      public void TestOverflowException()
      {
         int i = obj.Add(int.MaxValue, int.MaxValue);
      }
   }

Verification of the Function return values.
There are some classes in the unit testing framework from which you can test your expectations or actual result.

1 - Assert - Description of the methods in this class are here
2 - CollectionAssert - Description of the methods in this class are here 

You can check here to get more detail and more attributes about this testing framework.

TDD (Test Driven Development) .Net

In this post I am going to explain a little bit about the TDD, code coverage and feature coverage.

What is TDD? Simply Test Driven Development, what does it mean? It means that you are going to make your test cases first and then you are going to write minimum amount of code to pass all the test cases.

Not all the classes can be tested 100% because of some DB limitations or web service limitations or sometimes related to views or events but 50% of them that have limitation can be mocked and tested. Later on in my posts I will discuss about mocking but right now I am going to talk about a simple method 'Add' that takes two integer and returns an integer value. The code snippet will be in C# .

      public int Add(int a, int b) //prototype

What you expect from the signature what it should perform? Simply it will take two integer values and return the sum of them. e.g. 2 + 3 = 5. I am assuming the class name will be Maths.

Here's a Unit test of it.

   [TestClass]
   public class MathsTest
   {
         Maths obj;
      [TestInitialize]
      public void Setup()
      {
             obj = new Maths();
      }

      [TestCleanup]
      public void Cleanup()
      {
          //dispose any object or cleanup DB
      }

      [TestMethod]
      public void TestMethod1()
      {
         Assert.IsTrue(obj.Add(2, 3) == 5);
      }
   }

Now our test class is completed and now we can write a code for the Maths class. So here's the code snippet of Maths class with 'Add' function.

 public class Maths
   {
      public int Add(int a, int b)
      {
         return a + b;
      }
   }

Is it completed? We have tested this method so it should be but my answer is no, we have got a 100% coverage of the code but we have not tested it completely. So what are the missing functionalities and missing test cases. Following are the listed below.

1 - The arguments are not tested on the minimum values of integer.
2 - The arguments are not tested on the maximum values of integer.
3- The arguments are not tested on the negative values of integer.

Let's test the #2 test case. I expect if I am providing the max value of int type and it returns int type value then it should raise an exception.

      [TestMethod]
      [ExpectedException(typeof(OverflowException))]
      public void TestOverflowException()
      {
         int i = obj.Add(int.MaxValue, int.MaxValue);
      }

Run and test it, is it raising exception. No, why? Why it is not raising exception because there is a fault in a very simple code. Instead of writing the above one it should be like below. Just replace return line with this one.
         return checked(a + b);

Now run it, it is perfectly working as expected.

So you have seen how much the test cases are important. You can try yourself the other test cases as well.

There is one misconception if your class code is traversed 100% by your test class then it won't be a 100% test coverage until you have covered all the test cases as well. Hope this will help you in writing the code.

My next post will be about a design pattern of a unit test that you should follow.  

Wednesday, April 10, 2013

Amazon S3 file download

A code snippet to download files from S3 by providing rootbucket, access key and secret key.


 AmazonS3 _client;  
 using (_client = Amazon.AWSClientFactory.CreateAmazonS3Client(accesskey, secretkey))  
 {  
      var util = new TransferUtility(_client);  
      var request = new TransferUtilityDownloadRequest()  
           .WithBucketName(rootbucket)  
           //e.g. full path is sohail/video/123.mp4  
           // root bucket is sohail, video/123.mp4 is WithKey  
     .WithKey(at which location have to download S3 file)   
           // Where to download location of hard disk.  
     .WithFilePath(ToDownloadPath);  
   util.Download(request);  
 }  

Files Downloader by extension from webpage


Download the files just providing the url and the desired extensions. Create a folder where the downloaded files will be placed. D:\FileDownloaderPath1\

Note: the .net framework must be available.

This will download those files that are linked via anchor tag.

It can be downloaded from the below URL.

FilesDownloader App

Tuesday, April 9, 2013

WMI and Custom configuration with multiple hierarchies


Please find the below link that will show how to use Multiple custom configuration hierarchy and WMI management.

WMI and Custom Configuration

Description
In the configuration file a custom configuration can be made to handle the services on a server. This configuration is using  a multiple hierarchy. So the following classes are being used to manage the multiple custom configuration.

ConfigurationSection
ConfigurationElement
ConfigurationElementCollection

Second thing, WMI will use that configuration and the relevant services on the specified server and will show in a grid. It can be stopped and started again via a desktop client.

Note: I have not used threading yet. This is just a demo so if a form hangs on then do wait.
Following classes are used to handle remote services.
ConnectionOptions
ManagementScope
ManagementObjectSearcher
ManagementObject

Monday, January 14, 2013

QueryRange error

Some of the time when you are applying expression in a QueryRange, you may get this error.

Query extended range failure: Right parenthesis expected near pos ....

There is a minor fix of this issue.

See the difference in both expressions.

This will produce error. Syntax wise it is correct but there is a minor error.

queryBuildRange.value(strFmt('(ItemType == %1 || ItemId == "%2")', 
    any2int(ItemType::Service),
    queryValue("B-R14")));


This will work fine.


queryBuildRange.value(strFmt('((ItemType == %1) || (ItemId == "%2"))', 
    any2int(ItemType::Service),
    queryValue("B-R14")));



Got the difference in both queries?

Yes, the every sub expression must be enclosed in the round bracket. See in the above one (ItemType == %1 && ItemId == %2), there is no round bracked enclosed with the expression. In the other one brackets are enclosed.

Copied the code from
http://www.axaptapedia.com/Expressions_in_query_ranges






Thursday, December 27, 2012

LINQ Join Query

    class Employee  
    {  
      public int EmployeeID { get; set; }  
      public string EmployeeName { get; set; }  
      public int DeptId { get; set; }  
    }  
    class Dept  
    {  
      public int DeptId { get; set; }  
      public string DeptName { get; set; }  
    }  
      List<Dept> dept = new List<Dept>();  
      List<Employee> emp = new List<Employee>();  
      dept.AddRange(new Dept[]   
      {   
       new Dept{ DeptId=1, DeptName="IT" },  
       new Dept{ DeptId=2, DeptName="Engineering" }  
      });  
      emp.AddRange(new Employee[]  
      {  
       new Employee{EmployeeID = 1, DeptId = 1, EmployeeName="Sohail"},  
       new Employee{EmployeeID = 2, DeptId = 1, EmployeeName="Zeeshan"},  
       new Employee{EmployeeID = 3, DeptId = 2, EmployeeName="Zubair"},  
      });  
      emp.Join(dept, empRow => empRow.DeptId, deptRow => deptRow.DeptId, (selectEmpRow, selectDeptRow) =>  
       new  
       {  
         EmpId = selectEmpRow.EmployeeID,  
         EmpName = selectEmpRow.EmployeeName,  
         DeptName = selectDeptRow.DeptName  
       })  
       .ToList()  
       .ForEach(_ => { Console.WriteLine("{0} {1} {2}", _.EmpId, _.EmpName, _.DeptName); });  

Wednesday, December 26, 2012

Linq GroupBy with Aggregate functions

 List<Employee> empList = new List<Employee>();  
       empList.AddRange(new Employee[]   
       {   
         new Employee {EmpId =1, DeptId=1, Position="Director", Salary=100 },  
         new Employee {EmpId =2, DeptId=1, Position="Director", Salary = 120},  
         new Employee {EmpId =3, DeptId=1, Position="Software Engineer", Salary=50 },  
         new Employee {EmpId =4, DeptId=2, Position="Director", Salary=90 },  
         new Employee {EmpId =5, DeptId=2, Position="Director", Salary=100 },  
         new Employee {EmpId =6, DeptId=3, Position="HR Assistant", Salary=40 },  
         new Employee {EmpId =7, DeptId=3, Position="HR Manager", Salary=70},  
         new Employee {EmpId =8, DeptId=4, Position="IT Manager", Salary=85 },  
         new Employee {EmpId =8, DeptId=4, Position="IT Assistant", Salary=40 }  
       });  
   
       /*  
        * The highest salary from the each dept per position  
       */  
       empList.GroupBy(_ => new { _.DeptId, _.Position })  
         .Select(_ => new  
         {  
           MaximumSalary = _.Max(deptPositionGroup => deptPositionGroup.Salary),  
           DepartmentId = _.Key.DeptId,  
           Position = _.Key.Position  
         }).ToList()  
         .ForEach(selectedRecords =>  
         {  
           Console.WriteLine("{0} {1} {2}", selectedRecords.DepartmentId, selectedRecords.Position, selectedRecords.MaximumSalary);  
         });  
   
       /*Average salary from each dept per position */  
   
       Console.WriteLine();  
       Console.WriteLine();  
       Console.WriteLine();  
       empList.GroupBy(_ => new { _.DeptId, _.Position })  
               .Select(_ => new  
               {  
                 AverageSalary = _.Average(deptPositionGroup => deptPositionGroup.Salary),  
                 DepartmentId = _.Key.DeptId,  
                 Position = _.Key.Position  
               }).ToList()  
               .ForEach(selectedRecords =>  
               {  
                 Console.WriteLine("{0} {1} {2}", selectedRecords.DepartmentId, selectedRecords.Position, selectedRecords.AverageSalary);  
               });  
       Console.WriteLine();  
       Console.WriteLine();  
       Console.WriteLine();  
       /*Average salary from each dept */  
       empList.GroupBy(_ => _.DeptId)  
               .Select(_ => new  
               {  
                 AverageSalary = _.Average(deptPositionGroup => deptPositionGroup.Salary),  
                 DepartmentId = _.Key,  
               }).ToList()  
               .ForEach(selectedRecords =>  
               {  
                 Console.WriteLine("{0} {1}", selectedRecords.DepartmentId, selectedRecords.AverageSalary);  
               });  

Tuesday, December 18, 2012

Convert Dictionary into Strongly Typed Class


There are few things you have to consider before conversion of dictionary into strongly typed class object.

1 - To detect in which class you want to convert into dictionary. For this purpose you need generic (Template) where you will specify in which class you want to convert.

2 - Get the properties of the strongly typed class using reflection.

3 - Create the object of the Generic . and get the reference of it.

4 - Iterate the properties of object and search the dictionary contains that field or column, if its find and writeable then set the value using reflection but cast the values into the strongly typed of a column too.

Here's the demo.

   class Emp {
      public string Name { get; set; }
      public string TechnologyExpert { get; set; }
      public int Salary { get; set; }
      public override string ToString(){
         return Name + "-----" + TechnologyExpert + "-----" + Salary;
      }
   }
   class Cust{
      public string Name { get; set; }
      public string Company { get; set; }
      public override string ToString(){
         return Name + "------" + Company;
      }
   }

/// Please use angle bracket here too.
   class ConvertIntoStronglyTyped  where T: new() {
      public static T ConvertMe(Dictionary objectDict)
      {
         var properties = typeof(T).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
       
         Object obj = new T();
       
         foreach (var property in properties)
            if (property.CanWrite && objectDict.ContainsKey(property.Name))            
               property.SetValue(obj, Cast(property.PropertyType.FullName, objectDict[property.Name]), null);                  

         return (T)obj;
      }

      private static object Cast(string propertyTypeName, object value) {
         string strFullName = typeof(string).FullName;
         string intFullName = typeof(int).FullName;
         string floatFullName = typeof(float).FullName;

         if (strFullName == propertyTypeName)   return value.ToString();
         if (intFullName == propertyTypeName)   return int.Parse(value.ToString());
         if (floatFullName == propertyTypeName) return int.Parse(value.ToString());
       
         return value;
      }
   }

Execute the code.

class Program
   {
      static void Main(string[] args)
      {
         Dictionary consolidatedValues = new Dictionary();
       
         consolidatedValues.Add("Name", "Sohail");
         consolidatedValues.Add("TechnologyExpert", "C#");
         consolidatedValues.Add("Salary", "200");
         consolidatedValues.Add("Company", "ABC .Com");

// I noticed the less than greater than bracket is not visible, use simple the angle brackets.
         Emp emp = ConvertIntoStronglyTyped&ltEmp&gt.ConvertMe(consolidatedValues);

         Cust cust = ConvertIntoStronglyTyped.ConvertMe(consolidatedValues);
         Console.WriteLine(emp);
         Console.WriteLine(cust);
      }
   }

Please let me know incase you are facing issue and have more questions regarding the reflections or generics.




Wednesday, June 8, 2011

demo project convert Datatable to LIST


You can find the project here

Explanation of both conversions from DataTable to List using Reflection and LINQ are already explained in the previous posts.

Friday, May 20, 2011

Convert datatable into list using reflection

Using reflection we can convert the datatable into strongly typed collection. I'll prefer list as a collection.

Let's suppose I have a class of Emp and I have put two fields in it. 
class Emp{ string Id {get; set;} string Name{get; set;}}
Now, to convert datatable into any class, Ofcourse we'll have to use Generic template that will find the type of the class. 
We are creating a class that will convert Datatable into strongly typed list. 

This is the declaration of a class where we will refer any business class as a 'T' and that 'T' type should have a constructor with no arguments. We are ensuring in the where. 
public class DatatableToListMapper : where T : new()
We will create a method ConvertDataTableIntoList where Datatable will be passed as an argument and this method will return List of type T.
Here's the signature of the method.
List ConvertDataTableIntoList(DataTable dt)
// create list of type T.
List objT = new List();
Now we will fetch every row from the DataTable.
foreach(DataRow dr in dt.Rows)
Now we will get the properties of the T class using the method typeof(T).GetProperties() and will retrieve every property using loop. Create an object of type T.

e.g. 
T obj = new T();
foreach(var property in typeof(T).GetProperties()){
property.SetValue(obj, dr[property.Name], null); /// Setting the property value in the object obj.
}
//Add this object in a 
objT.Add(obj);

At last return the object of list after conversion. I'll share the code in the next post where the mapping can be user defined using a Dictionary collection.


return objT;


Thursday, May 19, 2011

Convert Datatable into collection using LINQ

We can create the anonymous type from the data table but If we are interested to convert data table into strongly typed collection like List of Emp type from the datatable. Below is the code snippet.

    public class Emp
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

                DataTable dt = new DataTable();
                dt.Columns.Add("EmpId");
                dt.Columns.Add("EmpName");
                dt.Rows.Add("1", "Sohail");
                dt.Rows.Add("2", "Yasir");
                dt.Rows.Add("3", "Shahid");
Convert data type into AsEnumerable and then select the rows from the table and put one by one field in the emp object.
             List emp = new List();
             var result = from p in dt.AsEnumerable()
             select new Emp
             {
                     Id = int.Parse(p[0].ToString()),
                     Name = p[1].ToString()
             };

          After all, convert the result into List of Emp type.
           emp = result.ToList();       
           foreach (var row in emp)
           Console.WriteLine("{0}, {1}", row.Id, row.Name);

Friday, April 29, 2011

Defaulting Dimension in AX

What is defaulting dimension means?

Defaulting dimension means to provide the default values to the generated ledger dimension account from the originating account if the dimension values are empty for the generated ledger dimension.

For example:

If I give Mainaccount-Fund as a dimension structure.

LedgerDimensionOriginatingAccount = 10200 - 100
LedgerDimensionGeneratedAccount = 10200 - --(empty)

After processing defaulting dimension, a new ledger dimension will be generated and 10200-100 will be a new ledger dimension. I will share the code in the next post how to the dimension defaulting can be done.




Sunday, April 24, 2011

Convert object into anonymous type C#

Firstly I want to tell you that to use anonymous types isn't best practice. I was thinking if we can parse anonymous type into object then object should be parsed into anonymous type too.

here's an example.
lets suppose, we create a list of object type and we add some items in it of a anonymous type.

List obj = new List();

obj.Add((object)new {Id=1, Name="S"});
obj.Add((object)new {Id=2, Name="N"});
obj.Add((object)new {Id=3, Name="NS"});



 In the above list, I have added three objects. How can I retrieve the Id and Name attribute. There are two possibilities one we can create a strongly typed class but that will waste the purpose of a Anonymous type and the other one is to use using Generics or Templates. I will create a small method that will convert object into Anonymous type and will be available for querying the data in the code... 
public static T ConvertObjectIntoAnonymousType(T object, T typeOfObject) {         
return (T)object; 
}
 How we will use this function. 
object o = obj[0]; 



var anonymousObject = ConvertObjectIntoAnonymousType(o, new {Id=0, Name=""}); 


Its been converted. What we did? We created a anonymous type in the second argument of the same as we have the list object type. This type will be hold in T of the function ConvertObjectIntoAnonymousType and will be able to cast object into type T that is anonymous type. Using this technique we can save the time to create classes. I used this technique when I was using deserializing the dataset's XML for querying data. Hope this would help to everyone.

Thursday, April 14, 2011

Dimension framework in Microsoft Dynamics AX 2012

AX has introduced dimension framework. A detailed white paper is available on the below link.

Accounts and Financial dimension framework.

Let me know in case of any query regarding accounts dimension or financial dimensions.

The Intelligent Data Management in MS Dynamics AX

Find the attached link of a presentation that is delivered by Tao Wang Principle Development Manager of AX Performance.
Intelligent Data Management in MS Dynamics AX presentation link.

Wednesday, March 2, 2011

Configure and update OLAP cubes



Note: Make sure you have configuration/license keys configured, otherwise the dimensions that have no access of the field of OLTP will be removed.


Step # 1:


OLTP database synchronization of OLAP tables:


    The following procedure is used to update the BI tables that are purely related to BI cubes and used as a   dimension in the BI cubes. Before executing the procedure you need to perform some pre-requistes listed below:
1 - Go into Administration tab> Setup> Business Analysis> OLAP and click on OLAP Administration.
2 - A form will be opened.
3 - Go onto the Advanced tab of the form and mark the checkbox 'Update BI Data'.
4 - Press the button 'Update database'
You will observe that the BI related tables are filled and now these tables can be used for BI analysis after processing.


Step # 2:


OLAP database synchronization with OLTP database:

We know that OLAP has a different schema and is mapped directly to the OLTP tables in order to provide the records in OLAP cube's dimensions and measures.
Same form will be used to synchronize OLAP database. The only difference is that  here we need to provide the datasource and the server where the OLAP database schema exist. For  this task follow the steps below:
1 - Go onto OLAP Administration form.
2 - A form will be opened.
3 - Go onto the OLAP servers tab. Select the server (instance)
4 - Go onto the OLAP databases tab. Select the OLAP database.
5 - Now go onto the advanced tab, click on the checkbox Synchronise OLAP database with OLTP schema.
6 - Click update database button.
This will update the OLAP schema. Same procedure will be applied if you want database changes to be shown in OLAP schema after inserting any records in OLAP tables like CustTrans (When creating FTI), PurchTrans, LedgerTrans etc.

Soon, I will talk about how to update the OLAP database incase if you have any tables and want to use as a dimension and measures in the OLAP cubes..

Monday, August 23, 2010

Introduction to Role Center

Role Centers are default home pages for AX client and EP that provide an overview of the information that pertains to the work of people such as CFOs, CEOs, Accountants... It consist of the following web parts:

1 - Work list
2 – Activities
3 - Frequently used links
4 - Business intelligence information.
a) KPIs (Business Overview webpart)
b) KPI Reports

There is difference between the Role center page that displays on AX Client and on EP. Client Forms will not be visible and cannot be opened from the EP but can be accessed from the AX Client.

1 – Unified Work list web part:
The Dynamics Unified Work list Web part displays the list of activities, alerts, workflow approvals, and workflow tasks.
It can be added using
a - Add a web part on EP page
b – Select Dynamics AX and Select ‘Unified work list’ webpart.

2 – AX Report web part:
The AX report web part is usually used to show reports on a role center.

3 – Quick Links web part
Quick links web part provides a quick access to EP pages, reports and forms. Usually we group Quick Links into two parts.
a - Form Links
b - Report Links
AX Client Form links can be accessed only from the Role Center. AX forms cannot be accessed from the EP.

4 – Activity web part
The activity web part can be used to see the information in terms of statistical data. The activity web part shows the information according the query defined for it.

Sunday, August 15, 2010

show container values in a hierarchy

There is an existing form 'SysConView' that is used to retrieve values from container to show on a form. Here is a simple example how to show a hierarchical structure on a form. conView method is used to display container values that exist in a Global class.

container myContainer;
container myChildContainer;

myContainer = [1, 2, 3, 4, 5];
myChildContainer = [6, 7, 8, 9, 10];
/* Add a child container in myContainer*/
myContainer += [myChildContainer];
myContainer += ['Sohail'];

conView(myContainer);