Development Simply Put

A blog simplifies main concepts in IT development and provides tips, hints, advices and some re-usable code. "If you can't explain it simply, you don't understand it well enough" -Albert Einstein

  • Development Simply Put

    If you can't explain it simply, you don't understand it well enough.

    Read More
  • Integrant

    Based in the U.S. with offshore development centers in Jordan and Egypt, Integrant builds quality custom software since 1992. Our staff becomes an extension of your team to eliminate the risks of software development outsourcing and our processes...

    Read More
  • ITWorx

    ITWorx is a global software professional services organization. Headquartered in Egypt, the company offers Portals, Business Intelligence, Enterprise Application Integration and Application Development Outsourcing services to Global 2000 companies.

    Read More
  • Information Technology Institute

    ITI is a leading national institute established in 1993 by the Information and Decision Support Centre.

    Read More

2018-05-13

Usages Of MSSQL ROW_NUMBER()



ROW_NUMBER is an analytic function. It assigns a unique number to each row to which it is applied (either each row in the partition or each row returned by the query), in the ordered sequence of rows specified in the order_by_clause, beginning with 1.

If you want to know more about the definition you can find many resources on the internet talking about ROW_NUMBER. The main focus of this article would be about the usages with providing some code samples.

All code samples for this article could be found on this GitHub repository.

Creating Test Table:

First create a test database and run the script below to create our test table.


Inserting Data:

Run this script to insert some data in our test table.




Basic Syntax:

The basic syntax of ROW_NUMBER is as follows.


As you can see the syntax consists of "ROW_NUMBER()" followed by an "OVER" clause. In the "OVER" clause you should specify the ordering of your records which is essential before requesting from SQL server to number your rows. This is done as in the "OVER (ORDER BY Name, Subject)" clause. In this case, we are ordering the records by "Name" then "Subject" and both in ascending order.

Running this query we will get the results below.


This is not all. Also, we can use the "PARTITION BY" clause in addition to the "ORDER BY" clause as in the code below.

In this code sample, we added the "PARTITION BY" clause which divides/partitions/splits the records into partitions/groups according to the criteria defined before starting the numbering process. In this case, we decided to partition the records using the "Name" column. This means that the records will be divided into groups where the records in each group have the same value in the "Name" column. Then, the row numbering process starts which means that the numbering would be reset at the beginning of each group. In easy words we can say that the "PARTITION BY" clause divides the records into groups and then the whole process (ROW_NUMBER, SUM, ....) will be applied separately on each group.

So, running this query we will get the results below.


Deleting Duplicate Records:

As you can see we have some duplicate records in our test table and by duplicate we mean that some records have the same "Name, Subject" combination. For sure they have different "Id" but assume that according to our business requirements these records should be treated as duplicates and this is caused by a wrong implementation which we need to fix. So, now we need to delete all duplicates and leave only one of each.

As you can see in the code sample, we are calculating the row number while partitioning with "Name, Subject" and ordering with "Name, Subject". This means that the numbering will be reset for each group of "Name, Subject" combination which means that if we have some student taking some subject and this record has duplicates, there would be row numbers greater than 1. Then, using this piece of info we can detect the duplicate records to be deleted.

Running this query we will get the results below.


Looping On Records (Without Using Cursors):

You can also make use of ROW_NUMBER in looping through records as in the code sample below.

Running this query we will get the results below.


Paging:

You can also make use of ROW_NUMBER in paging records as in the code sample below.

Running this query we will get the results below.



And if we set @pageSize to 1 and @pageIndex to 1, we will get the results below.



And if we set @pageSize to 5 and @pageIndex to 1, we will get the results below.



 And if we set @pageSize to 5 and @pageIndex to 6, we will get the results below.



Paging By Group:

You can also make use of ROW_NUMBER in paging records by groups so that you can process each group separately. This is done as in the code sample below.

Running this query we will get the results below.



I am now done and I encourage you to do your research on "ROW_NUMBER" as it has many usages. The ones I mentioned here are just some examples but I am sure there are a lot of other examples and usages.


2018-03-10

TDD and Automated Unit Testing for Console Application




You can find the code samples used in this post on this GitHub repository.


Some friends of mine complained that sometimes they are not able to apply TDD or write automated unit tests for some kinds of modules or applications and the one on the top of these kinds is Console applications. How could I test a console application when the input is passed by key strokes and the output is presented on a screen?!!

Actually this happens from time to time, you find yourself trying to write automated unit tests for something you seem to not have any control upon. But, the truth is, you just missed the point, you don't want to test the "Console" application, you want to test the business logic behind it.

When building a Console application, you are building an application for someone to use, he expects to pass some inputs and get some corresponding outputs and that's what you really need to test. You don't want to test the "System.Console" static class, this is a built-in class that is included in the .NET framework and you have to trust Microsoft on this. So, this leads us to the next point.

After pinpointing what you really want to test and what you don't, you have to think how to separate these two areas into separate components or modules so that you can start writing tests for the one you desire without interfering with the other one. And that is what we are going to do in the rest of the post.

Here is what we are going to do:
1. Build a simple (trivial) Console application first in the bad way
2. Re-implement it in the good way
3. Write some automated unit tests

1. Build a simple (trivial) Console application first in the bad way

Here is what we are going to build.






Create a VS project of type "Console Application" and name it "MyConsoleApp". Change the code inside the "Program" class to be as follows.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = string.Empty;

            do
            {
                Console.WriteLine("Welcome to my console app");
                Console.WriteLine("[1] Say Hello?");
                Console.WriteLine("[2] Say Goodbye?");
                Console.WriteLine("");
                Console.Write("Please enter a valid choice: ");

                input = Console.ReadLine();

                if (input == "1" || input == "2")
                {
                    Console.Write("Please enter your name: ");
                    string name = Console.ReadLine();

                    if (input == "1")
                    {
                        Console.WriteLine("Hello " + name);
                    }
                    else
                    {
                        Console.WriteLine("Goodbye " + name);
                    }

                    Console.WriteLine("");
                    Console.Write("Press any key to exit... ");
                    Console.ReadKey();
                }
                else
                {
                    Console.Clear();
                }
            }
            while (input != "1" && input != "2");
        }
    }
}

2. Re-implement it in the good way

Create a "ConsoleManager" class library project and add the following classes to the project.

IConsoleManager.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
using System;

namespace ConsoleManager
{
    public interface IConsoleManager
    {
        void Write(string value);
        void WriteLine(string value);
        ConsoleKeyInfo ReadKey();
        string ReadLine();
        void Clear();
    }
}

ConsoleManagerBase.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleManager
{
    public abstract class ConsoleManagerBase : IConsoleManager
    {
        public abstract void Clear();
        public abstract ConsoleKeyInfo ReadKey();
        public abstract string ReadLine();
        public abstract void Write(string value);
        public abstract void WriteLine(string value);
    }
}

ConsoleManager.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using System;

namespace ConsoleManager
{
    public class ConsoleManager : ConsoleManagerBase
    {
        #region ConsoleManagerBase Implementations
        public override void Clear()
        {
            Console.Clear();
        }
        public override ConsoleKeyInfo ReadKey()
        {
            return Console.ReadKey();
        }
        public override string ReadLine()
        {
            return Console.ReadLine();
        }
        public override void Write(string value)
        {
            Console.Write(value);
        }
        public override void WriteLine(string value)
        {
            Console.WriteLine(value);
        }
        #endregion
    }
}

ConsoleManagerStub.cs
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleManager
{
    public class ConsoleManagerStub : ConsoleManagerBase
    {
        #region Fields
        private int currentOutputEntryNumber = 0;
        private Queue<object> userInputs = new Queue<object>();
        private List<string> outputs = new List<string>();
        #endregion

        #region Properties
        public Queue<object> UserInputs
        {
            get
            {
                return userInputs;
            }
        }
        public List<string> Outputs
        {
            get
            {
                return outputs;
            }
        }
        #endregion

        #region Events
        public event Action<int> OutputsUpdated;
        public event Action OutputsCleared;
        #endregion

        #region ConsoleManagerBase Implementations
        public override void Clear()
        {
            currentOutputEntryNumber++;
            outputs.Clear();
            OnOutputsCleared();
            OnOutputsUpdated(currentOutputEntryNumber);
        }
        public override ConsoleKeyInfo ReadKey()
        {
            ConsoleKeyInfo result = new ConsoleKeyInfo();
            object input = null;

            if (userInputs.Count > 0)
            {
                input = userInputs.Dequeue();
            }
            else
            {
                throw new Exception("No input was presented when an inpput was expected");
            }

            if (input is ConsoleKeyInfo)
            {
                result = (ConsoleKeyInfo)input;
            }
            else
            {
                throw new Exception("Invalid input was presented when ConsoleKeyInfo was expected");
            }

            return result;
        }
        public override string ReadLine()
        {
            string result = null;
            object input = null;

            if (userInputs.Count > 0)
            {
                input = userInputs.Dequeue();
            }
            else
            {
                throw new Exception("No input was presented when an inpput was expected");
            }

            if (input is string)
            {
                result = (string)input;
                WriteLine(result);
            }
            else
            {
                throw new Exception("Invalid input was presented when String was expected");
            }

            return result;
        }
        public override void Write(string value)
        {
            outputs.Add(value);
            currentOutputEntryNumber++;
            OnOutputsUpdated(currentOutputEntryNumber);
        }
        public override void WriteLine(string value)
        {
            outputs.Add(value + "\r\n");
            currentOutputEntryNumber++;
            OnOutputsUpdated(currentOutputEntryNumber);
        }
        #endregion

        #region Events Handlers
        protected void OnOutputsUpdated(int outputEntryNumber)
        {
            if (OutputsUpdated != null)
            {
                OutputsUpdated(outputEntryNumber);
            }
        }
        protected void OnOutputsCleared()
        {
            if (OutputsCleared != null)
            {
                OutputsCleared();
            }
        }
        #endregion

        #region Object Overrides
        public override string ToString()
        {
            string result = string.Empty;

            if (outputs != null && outputs.Count > 0)
            {
                StringBuilder builder = new StringBuilder();

                foreach (string output in outputs)
                {
                    /*if (output.Contains("\n"))
                    {
                        string[] parts = output.Split('\n');

                        foreach (string part in parts)
                        {
                            if (!string.IsNullOrEmpty(part))
                            {
                                builder.AppendLine(part);
                            }
                        }
                    }
                    else
                    {
                        builder.Append(output);
                    }*/

                    builder.Append(output);
                }

                result = builder.ToString();
            }

            return result;
        }
        #endregion
    }
}


Apply the following modifications to the "MyConsoleApp" project after installing the Nugget package "Ninject".

Add ProgramManager.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using ConsoleManager;

namespace MyConsoleApp
{
    public class ProgramManager
    {
        #region Fields
        private IConsoleManager consoleManager = null;
        #endregion

        #region Constructors
        public ProgramManager(IConsoleManager consoleManager)
        {
            this.consoleManager = consoleManager;
        }
        #endregion

        #region Methods
        public void Run(string[] args)
        {
            string input = string.Empty;

            do
            {
                consoleManager.WriteLine("Welcome to my console app");
                consoleManager.WriteLine("[1] Say Hello?");
                consoleManager.WriteLine("[2] Say Goodbye?");
                consoleManager.WriteLine("");
                consoleManager.Write("Please enter a valid choice: ");

                input = consoleManager.ReadLine();

                if (input == "1" || input == "2")
                {
                    consoleManager.Write("Please enter your name: ");
                    string name = consoleManager.ReadLine();

                    if (input == "1")
                    {
                        consoleManager.WriteLine("Hello " + name);
                    }
                    else
                    {
                        consoleManager.WriteLine("Goodbye " + name);
                    }

                    consoleManager.WriteLine("");
                    consoleManager.Write("Press any key to exit... ");
                    consoleManager.ReadKey();
                }
                else
                {
                    consoleManager.Clear();
                }
            }
            while (input != "1" && input != "2" && input != "Exit");
        }
        #endregion
    }
}

Add NinjectDependencyResolver.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
using Ninject.Modules;
using ConsoleManager;

namespace MyConsoleApp
{
    public class NinjectDependencyResolver : NinjectModule
    {
        public override void Load()
        {
            Bind<IConsoleManager>().To<ConsoleManager.ConsoleManager>();
        }
    }
}

Update Program.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using ConsoleManager;
using Ninject;
using System.Reflection;

namespace MyConsoleApp
{
    class Program
    {
        #region Fields
        private static ProgramManager programManager = null;
        private static IConsoleManager consoleManager = null;
        #endregion

        static void Main(string[] args)
        {
            StandardKernel kernel = new StandardKernel();
            kernel.Load(Assembly.GetExecutingAssembly());
            consoleManager = kernel.Get<IConsoleManager>();
            
            programManager = new ProgramManager(consoleManager);
            programManager.Run(args);
        }
    }
}

3. Write some automated unit tests

Create a "MyConsoleApp.Tests" class library project, install the Nugget package "NUnit", from VS Tools > Extensions and Updates > Search online for "Nunit Test Adapter" and install it and finally add the following classes to the project.

ProgramManagerTests.cs
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
using ConsoleManager;
using NUnit.Framework;
using System;
using System.Collections.Generic;

namespace MyConsoleApp.Tests
{
    [TestFixture]
    public class ProgramManagerTests
    {
        #region Fields
        private ConsoleManagerStub consoleManager = null;
        private ProgramManager programManager = null;
        #endregion

        [SetUp]
        public void SetUp()
        {
            consoleManager = new ConsoleManagerStub();
            programManager = new ProgramManager(consoleManager);
        }

        [TearDown]
        public void TearDown()
        {
            programManager = null;
            consoleManager = null;
        }

        [TestCase("Ahmed Tarek")]
        [TestCase("")]
        [TestCase(" ")]
        public void RunWithInputAs1AndName(string name)
        {
            consoleManager.UserInputs.Enqueue("1");
            consoleManager.UserInputs.Enqueue(name);
            consoleManager.UserInputs.Enqueue(new ConsoleKeyInfo());

            List<string> expectedOutput = new List<string>();
            expectedOutput.Add("Welcome to my console app\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: ");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: 1\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: 1\r\nPlease enter your name: ");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: 1\r\nPlease enter your name: " + name + "\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: 1\r\nPlease enter your name: " + name + "\r\nHello " + name +"\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: 1\r\nPlease enter your name: " + name + "\r\nHello " + name +"\r\n\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: 1\r\nPlease enter your name: " + name + "\r\nHello " + name +"\r\n\r\nPress any key to exit... ");

            consoleManager.OutputsUpdated += (int outputEntryNumber) => {
                Assert.AreEqual(expectedOutput[outputEntryNumber - 1], consoleManager.ToString());
            };

            programManager.Run(new string[] { });
        }

        [TestCase("Ahmed Tarek")]
        [TestCase("")]
        [TestCase(" ")]
        public void RunWithInputAs2AndName(string name)
        {
            consoleManager.UserInputs.Enqueue("2");
            consoleManager.UserInputs.Enqueue(name);
            consoleManager.UserInputs.Enqueue(new ConsoleKeyInfo());

            List<string> expectedOutput = new List<string>();
            expectedOutput.Add("Welcome to my console app\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: ");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: 2\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: 2\r\nPlease enter your name: ");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: 2\r\nPlease enter your name: " + name + "\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: 2\r\nPlease enter your name: " + name + "\r\nGoodbye " + name + "\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: 2\r\nPlease enter your name: " + name + "\r\nGoodbye " + name + "\r\n\r\n");
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: 2\r\nPlease enter your name: " + name + "\r\nGoodbye " + name + "\r\n\r\nPress any key to exit... ");

            consoleManager.OutputsUpdated += (int outputEntryNumber) => {
                Assert.AreEqual(expectedOutput[outputEntryNumber - 1], consoleManager.ToString());
            };

            programManager.Run(new string[] { });
        }

        [Test]
        public void RunShouldKeepTheMainMenuWhenInputIsNeither1Nor2()
        {
            consoleManager.UserInputs.Enqueue("any invalid input 1");
            consoleManager.UserInputs.Enqueue("any invalid input 2");
            consoleManager.UserInputs.Enqueue("Exit");

            List<string> expectedOutput = new List<string>();
            // initital menu
            expectedOutput.Add("Welcome to my console app\r\n"); // outputEntryNumber 1
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n"); // outputEntryNumber 2
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n"); // outputEntryNumber 3
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\n"); // outputEntryNumber 4
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: "); // outputEntryNumber 5
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: any invalid input 1\r\n"); // outputEntryNumber 6

            // after first trial
            expectedOutput.Add(""); // outputEntryNumber 7
            expectedOutput.Add("Welcome to my console app\r\n"); // outputEntryNumber 8
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n"); // outputEntryNumber 9
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n"); // outputEntryNumber 10
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\n"); // outputEntryNumber 11
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: "); // outputEntryNumber 12
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: any invalid input 2\r\n"); // outputEntryNumber 13

            // after second trial
            expectedOutput.Add(""); // outputEntryNumber 14
            expectedOutput.Add("Welcome to my console app\r\n"); // outputEntryNumber 15
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n"); // outputEntryNumber 16
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n"); // outputEntryNumber 17
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\n"); // outputEntryNumber 18
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: "); // outputEntryNumber 19
            expectedOutput.Add("Welcome to my console app\r\n[1] Say Hello?\r\n[2] Say Goodbye?\r\n\r\nPlease enter a valid choice: Exit\r\n"); // outputEntryNumber 20

            consoleManager.OutputsUpdated += (int outputEntryNumber) => {
                if ((outputEntryNumber - 1) < expectedOutput.Count)
                {
                    Assert.AreEqual(expectedOutput[outputEntryNumber - 1], consoleManager.ToString());
                }
            };

            programManager.Run(new string[] { });
        }
    }
}


That's it, now you have successfully written automated unit tests for a Console application.


You can find the code samples used in this post on this GitHub repository.

2018-02-04

What is TDD and Automated Unit Testing Part 3



This is a part from a series dedicated to TDD and Automated Unit Testing. I will try to do my best to keep this series alive and updated.


The series parts:

What is TDD and Automated Unit Testing Part 1
What is TDD and Automated Unit Testing Part 2
What is TDD and Automated Unit Testing Part 3


On the previous part of this series we were trying to dive in TDD and the world of automated unit testing and have a look on the best practices and the new habits you should gain, abide to and embrace to be able to keep up with that world.

We covered topics like:

  • Single Responsibility Principle
  • Inversion of Control (Ioc) / Dependency Inversion Principle
  • Dependency Injection Technique
  • Stubs


On this part we are going to discuss some important concepts and expressions you will for sure come across while diving in the world of TDD and automated unit testing.

So, the first thing to start with is “Mocks”.


What is Mocks?

As we have seen in the previous part of this series, we can use “Stubs” to have full control on the subject (class/method) we are testing. The main idea behind a “Stub” is to have a fake implementation of some dependency on which our subject depends. This provides us with a chance to isolate the subject from any other dependencies to make sure we are testing only the subject, not it’s dependencies as well. This way, whatever the results we get -a passing or failing test- we are sure that these results are triggered only by the subject and that’s what we are trying to do in the first place.

For “Mocks”, the same concept and the same goal is applied but with a different way of implementation. With mocks we don’t provide a full fake implementation of the dependencies, we just add some hooks on the abstractions of these dependencies and manipulate their behavior and adapt them to our needs. It’s like creating a stub with minimum effort and on the fly.

I know these words are not self-explanatory and that’s why we need to dive in more and see some examples of using mocks. But, before doing that let’s add an extra note. Mocks are usually applied using some third-party libraries, sure we can implement our mocking library ourselves but this is not the best thing to do, I would rather prefer to use one of these libraries because they are tested and used on too many projects and this is a great advantage if you ask me.

Now, enough with the talking and let’s see some examples.


“Mocks” examples

I thought about providing here some examples and code samples for using Mocks but I found out that these examples could be redundant and sometimes misleading if they got outdated. As I told you before, usually mocks are implemented using some third-party libraries and these libraries change from time to time due to updates and bug fixes. Also, the syntax and way of setup of each of these libraries is different and the knowledge of one of them might not work with another.

So, the best thing to do to see some examples is to check the documentations and code samples provided by these libraries son their pages and repositories.

For example. You can check the well-known “Moq” library for the .NET framework on its GitHub repository. It includes all kinds of examples and samples you may need.

Also, if you are a client-side developer, you can also apply TDD and automated unit testing using frameworks like Jasmine. Jasmin also has its own way of applying mocks, this way is called “Spies”. Using the “spyOn” method you can achieve the same results you get using the .NET “Moq” library.

If you want to have a look on some samples you can search the internet and you will find some results like this and this and many others.


Why to use “Mocks” when we have “Stubs”?

In most cases you would prefer to use mocks instead of stubs because as you can see that the amount of code, effort and time you need to achieve the same result using stubs would be significant and this is logical as with mocks you may implement only the portion you care about and it differs from one situation to another. On the other hand, with stubs you need to provide full implementation.

Also, one of the main differences is that with stubs you will have to create some stub classes and these classes will end up on some code file. I believe that this is not the best thing to do as these code files will pollute the entire solution with some code unrelated to the main business logic and its unit tests.

Also, due to the significant amount of code provided for a stub, it would be more probably to need to get back to the stub and apply some changes whenever the business logic changes and some changes are applied on the subject itself.

That’s my own point of view, you don’t have to abide to it but you can verify it.


So, why use Stubs at all?

Sometimes implementing a mock would be so difficult and challenging. In this kind of cases we can implement a Stub that handles all what we need and the implementation could be quite simple and easy. So, it is a compromise, you should trade something for another but at the end you will have a working solution.


Ok, that’s it for this part and I wish there would be coming parts where we would see some examples and practices.

2018-01-28

What is TDD and Automated Unit Testing Part 2



This is a part from a series dedicated to TDD and Automated Unit Testing. I will try to do my best to keep this series alive and updated.


The series parts:

What is TDD and Automated Unit Testing Part 1
What is TDD and Automated Unit Testing Part 2
What is TDD and Automated Unit Testing Part 3


On the first part of this series we found answers for questions like:

  • Why is testing important?
  • How could an experienced coder/developer miss some cases and scenarios and leave them uncovered?
  • Why should we make testing automated, isn’t it enough to do it manually?
  • Should we implement automated unit testing for the entire system?
  • What is TDD?
  • What is RGRR or Red Green Red Refactor?
  • Why the hassle of doing the last Red?
  • What about the way the testing code is written?
  • What is AAA?
  • What are Testing Frameworks and Test Runners?


Now, the main purpose for this post is to dive in TDD and the world of automated unit testing and have a look on the best practices and the new habits you should gain, abide to and embrace to be able to keep up with that world.

Let’s start with an important note, the best practices to be mentioned in this post are generally useful, not only in the world of TDD and automated unit testing, but also in the daily world of any software developer. So, one of the best advantages you can get while learning and practicing TDD and automated testing is learning new good habits.

That makes it obvious that the rest of this post will be about discussing the best practices and good habits you should learn while working with TDD and automated unit testing.


If you are going to write some code to test a method, it would be helpful to make this method as short and focused as possible (aka: Single Responsibility Principle)

When trying to write some code to test a business logic implementation method, you should keep in mind that this method should be short and focused as much as you can. This would help you so much when writing the testing code and would make it much easier. But what does it mean to make your method short and focused?

It means that you need to divide the business logic into smaller manageable parts and separate these parts into separate methods. Then, you can write testing code for every one of these methods separately. Also, it would be much easier to compile the unit test cases list.

I am sure you heard before about the widely known life concept of “Divide and Conquer”. But, I am also sure that you may have heard about some other software development concept and principle called “Single Responsibility Principle”. Actually, this is the concept we have been referring to since we started this section.

It states that every method of code you write should have only one reason to change. This means that when you start writing a method try to make its logic so focused on only one simple purpose. This way when requested changes time comes, you find that the changes you need to apply touch only one or two or a small number of controllable methods rather than touching one huge method in the core of the entire system.

Ok, but what about testing? I think it is logical that testing a simple method would be easier than testing a complex method.

For example, assume that your system would be a calculator. What would be easier for you, to test one method which takes as parameters; the operation type (add, subtract, multiply, …), the left hand-side operand and the right hand-side operand ……. or to test a group of methods each handles one certain operation?

For the first option, you must write test cases to test all combinations of these parameters beside writing other test cases to make sure that the implemented logic doesn’t confuse one operation to another. For example, the square root operation should only consider the left hand-side operand.

But, for the second option you must write simple defined test cases for each method knowing that there should not be any confusion between operations.

Also, what if a change request time has come and you need to apply a change to only one operation?For the first case it would be like hell to handle the change and considering all other parts of the system calling this method, which would be a quite number of parts and finally reviewing your already written test cases. But for the second case, it wouldn’t be that hard.


What if the method you are trying to test do some stuff like inserting a record in the database?

You are right, a method which do stuff like these is hard to test, but not always. It depends on the way this method is implemented. But first, let me show you the problem with an example which is much simpler than the one you are talking about just to show you that the cause of the problem is not the need to connect to a database, it is farther than that.

Assume that you have a method that just returns a message saying, “Hello system user, the time now is …”. How would you implement this method? Let me answer this question. You may implement it like this:

public string GetWelcomeMessage()
{
        return “Hello system user, the time now is ” + DateTime.Now.ToString();
}
  

Now, let’s write a testing method for this method…… Opps, I can’t even come up with a test case as I don’t have an expected value to compare to at the moment I am writing the test code. Every time the test method runs the expected value should change to reflect the date and time then. So, now what?

Someone may have a good suggestion. He may suggest modifying the method to be as follows:

public string GetWelcomeMessage(DateTime dateAndTime)
{
        return “Hello system user, the time now is ” + dateAndTime.ToString();
}
  

Ok, now you can write a working test case as follows:

public void ShouldReturnAWelcomeMessageWithCurrentDateAndTime()
{
DateTime now = DateTime.Now;
        Assert.AreEqual(“Hello system user, the time now is “ + now, GetWelcomeMessage(now));
}
  

That’s good but it could be better. Keep reading and you will see what I mean.


Dependency Inversion Principle

Dependency Inversion is a principle which states that higher modules should not depend on lower modules. On the other hand, they both should depend on abstractions rather than concretions. This means that if you have a module, and module here could be a method or a class, which depends on another module to be able to carry out its task(s), you should abstract the dependency in a separate layer and then each of these modules should refer to this layer and depend on it rather than depending on each other. To understand what I am trying to say here, let’s check an example.

Do you remember the “GetWelcomeMessage” method from the previous section? We will continue working on it trying to understand what we have in mind up till now.

We have two modules:

  1. The “GetWelcomeMessage” method
  2. The “DateTime.Now” property of the “DateTime” class

The first module is dependent on the second one as the first one can’t do what it should do without using the second module, this means that we have a dependency here.

To break this dependency, we need to abstract the dependency into a third layer and since this layer is by definition an abstract layer, we can make it an interface.

So, this means that we should have an interface like this:

public interface IDateTimeProvider
{
DateTime Now { get; };
}
  

That’s good, now, let’s modify the first module so that the dependency on the second module is broken.

public StandardDateTimeProvider : IDateTimeProvider
{
public DateTime Now
        {
        return DateTime.Now;
        }
}
  

public string GetWelcomeMessage()
{
        return “Hello system user, the time now is ”
                + new StandardDateTimeProvider().Now.ToString();
}
  

This way, the first module is no longer dependent on the second module. It is now dependent on another abstract layer which could be replaced by more than one concrete implementation and the choice of that concrete implementation could be considered.


Dependency Injection Technique and Stubs

After applying dependency inversion principle and inverting the dependency as we did in the previous section, we can now proceed to the next step. Now when we have an abstract layer of dependency, we can make the “GetWelcomeMessage” method be able to focus on its main task rather than any side tasks. So, let’s ask ourselves, what is the main task of the “GetWelcomeMessage” method in its final shape? Let me answer this question. Its main task is to return a well formatted message with some welcome message and a date and time, but, not some certain date and time, just the date and time the “StandardDateTimeProvider” class can provide it with.

But, what if I need to be able to exchange this “StandardDateTimeProvider” class with another, maybe because at some other places of the world the standard DateTime.Now will not return the date I want. Or maybe because I need to write some test code and I need to have some fixed value for date and time. So, what can I do about it?

Here comes the dependency injection technique. You can modify the “GetWelcomeMessage” method so that it takes an instance of any class which implements the interface “IDateTimeProvider” and then make the method uses this class instance rather than using the hardcoded “StandardDateTimeProvider” class instance. It would be like this:

public string GetWelcomeMessage(IDateTimeProvider dateTimeProvider)
{
        return “Hello system user, the time now is ” + dateTimeProvider.Now.ToString();
}
  

This way, at runtime we can just inject an instance of any class implementing the “IDateTimeProvider” interface and deciding which class to use could be done based on any kind of conditions or any purpose we have.

For example, to test the final “GetWelcomeMessage” method, we can just do as follows:

public DummyDateTimeProviderForTesting : IDateTimeProvider
{
public DateTime Now
        {
        return DateTime.Parse(“2018/01/27 10:50:00”);
        }
}
  

public void ShouldReturnAWelcomeMessageWithCurrentDateAndTime()
{
DateTime now = new DummyDateTimeProviderForTesting().Now;
        Assert.AreEqual(“Hello system user, the time now is “
                + now, GetWelcomeMessage(now));
}
  

This is great, right? Sure, it is great and let me tell you about something. Defining the new “DummyDateTimeProviderForTesting” class and using it for testing is what we call a Stub. The stub here is the “DummyDateTimeProviderForTesting” class and it means that you provided a fake implementation of a dependency of the method you are testing so that you can have expected results which you have full control on.

Let’s make it harder and see if the same concepts can hold on.


Back to the database example, what if the method you are trying to test do some stuff like inserting a record in the database?

Assume that the module you are trying to test is as follows:

public class EmployeeRepository
{
public int CreateEmployee(Employee employee)
        {
        //do some serious stuff and add the employee to the database and return its id
        }
        public Employee GetEmployeeById(int id)
        {
        //do some serious stuff and retrieve the employee from the database
        }
}
  

public class EmployeesManager
{
public Employee RegisterEmployeeToSystem(Employee employee)
        {
                EmployeeRepository employeeRepository = new EmployeeRepository();
        return employeeRepository.GetEmployeeById(
employeeRepository.CreateEmployee(employee));
        }
}
  
 
Now, you need to write some test code to test the “RegisterEmployeeToSystem” method. So, following the same principles and guidelines:

public interface IEmployeeRespository
{
        int CreateEmployee(Employee employee);
        Employee GetEmployeeById(int id);
}
  

public class EmployeeRepository : IEmployeeRespository
{
public int CreateEmployee(Employee employee)
        {
        //do some serious stuff and add the employee to the database and return its id
        }
        public Employee GetEmployeeById(int id)
        {
        //do some serious stuff and retrieve the employee from the database
        }
}
  

public class EmployeesManager
{
private IEmployeeRepository employeeRepository;
public EmployeesManager(IEmployeeRespository employeeRespository)
        {
        this.employeeRespository = employeeRespository;
        }
public Employee RegisterEmployeeToSystem(Employee employee)
        {
        return employeeRepository.GetEmployeeById(
                        employeeRepository.CreateEmployee(employee));
        }
}
  

public class DummyEmployeeRepositoryForTesting : IEmployeeRespository
{
private List employees = List();
private int counter = 0;
public int CreateEmployee(Employee employee)
        {
                counter++;
                Employee clone = Clone(employee);
                clone.Id = counter;
        employees.Add(clone);
        }
        public Employee GetEmployeeById(int id)
        {
        return employees.First(emp => emp.Id === id);
        }
        private Employee Clone(Employee employee)
        {
        //return a deep copy of the input employee
        }
}
  

public void ShouldAddAnEmployeeAndRetrieveItSuccessfully()
{
//Arrange
        DummyEmployeeRepositoryForTesting dummyRepo = new DummyEmployeeRepositoryForTesting();
EmployeesManager employeesManager = new EmployeesManager(dummyRepo);
Employee employeeToAdd1 = new Employee() { Name = “Ahmed”, Age = 33 };
        Employee employeeToAdd2 = new Employee() { Name = “Mohamed”, Age = 25 };
//Act
Employee employeeRetrieved1 = employeesManager.RegisterEmployeeToSystem(employeeToAdd1);
        Employee employeeRetrieved2 = employeesManager.RegisterEmployeeToSystem(employeeToAdd2);
//Assert
        Assert.IsTrue(employeeRetrieved1 !== null);         Assert.AreEqual(1, employeeRetrieved1.Id);
        Assert.AreEqual(employeeToAdd1.Name, employeeRetrieved1.Name);
        Assert.AreEqual(employeeToAdd1.Age, employeeRetrieved1.Age);
        Assert.IsTrue(employeeRetrieved2 !== null);         Assert.AreEqual(2, employeeRetrieved2.Id);
        Assert.AreEqual(employeeToAdd2.Name, employeeRetrieved2.Name);
        Assert.AreEqual(employeeToAdd2.Age, employeeRetrieved2.Age);
}
  

Ok, I believe that this was a good example to demonstrate the power of using these concepts and best practices, but, before leaving for today I should tell you that there is more to come.

For example, using stubs is not the only way to achieve what we have done up till now. There is something else called “Mocks” that is so powerful and you should know about and that’s why there would be a section on “Mocks” on the next part of the series.


That’s the end for today and see you on the next part.


Note:
All code samples included in this post are written on a text editor not an IDE, so, be a good spirit and don’t judge it if you find any mistakes 😊