Real Test Driven Development – Thinking of Money 14

 

right so we now need to display the balance, this is quite simple as we have a text box that is set to read only, and the balance is available form the engine, now we could add this balance to the current data grid controller, but I think the name is wrong so I shall rename it to the MoneyEngineController, so this will control all actions on the form.

looking at the controller code we can see that the only time the data is loaded is when the grid is bound, I think I will move that command up into the constructor, so when we create the controller, the data from the database is loaded ready, this will simplify the testing of the balance display and also leaves the data grid binding command doing a single thing, binding the data grid to the data source.

so we need a simple test to ensure we display the balance, I did a bit of refactoring on the test code, and ended up with the following test class

    [TestFixture]
    public class MoneyEngineControllerTests
    {
        ThinkingOfMoney.Controller.MoneyEngineController _Controller;

        [SetUp]
        public void SetupForTest()
        {
            _Controller = new ThinkingOfMoney.Controller.MoneyEngineController();
        }

        [Test]
        public void Hook()
        {
            Assert.IsTrue(true);
        }

        [Test]
        public void Create()
        {
            Assert.IsNotNull(_Controller);
        }

        [Test]
        public void BindDataGrid()
        {
            System.Windows.Forms.DataGridView gridView = new System.Windows.Forms.DataGridView();

            _Controller.BindDataGrid(gridView);

            Assert.IsTrue(gridView.Rows.Count == 0);
        }

        [Test]
        public void BindBalance()
        {
            System.Windows.Forms.TextBox txtBalance = new System.Windows.Forms.TextBox();
            _Controller.BindBalanceTextBox(txtBalance);

            Assert.IsTrue(txtBalance.Text.Length > 0, txtBalance.Text);
        }
    }

and the following code is now making up the controller, notice that I have formatted the output string(I found the information here) , and moved the loading code to the constructor.

    class MoneyEngineController
    {
        MoneyEngine.MoneyEngine _Engine;

        /// <summary>
        /// Initializes a new instance of the DataGridController class.
        /// </summary>
        public MoneyEngineController()
        {
            _Engine = new MoneyEngine.MoneyEngine();
            _Engine.LoadTransactions();         
        }

        public void BindDataGrid(System.Windows.Forms.DataGridView gridView)
        {
            gridView.DataSource = _Engine.History;
        }

        public void BindBalanceTextBox(System.Windows.Forms.TextBox txtBalance)
        {
            txtBalance.Text = string.Format("{0:c}", _Engine.Balance);
        }
    }

ok the test passes, we need to add the call to the form code, and run the form!

and the balance displays as zero, I was expecting more than that as some of the transactions have values in, so we do have a problem somewhere, looking at the code when we load the transactions from the database then the balance is not updated, so a quick change of code here, but first a test to prove the error and fix

        [Test]
        public void BalanceAfterLoad()
        {
            _Engine.LoadTransactions();

            Assert.IsTrue(_Engine.Balance > 0, "balance should be greater than zero");
        }

and as expected it fails, so now to update the load transactions method, to get a pass, first off started by changing the load class so it would use the available add and subtract routines that add too and subtract from the balance already, but I needed to be able to add the transaction id so update would work correctly

    public bool LoadTransactions()
        {
            DBMoneyEngine database = new DBMoneyEngine();
            DataTable transactions = database.GetTransactionsInDateOrder(ref _ErrorText);

            if (transactions == null)
                return false;

            if (transactions.Rows.Count > 0)
            {
                foreach (DataRow transData in transactions.Rows)
                {
                    Int32 transID = transData["TransID"] is DBNull ? 0 : Convert.ToInt32(transData["TransID"]);
                    TransactionType transType = transData["TransType"] is DBNull ? 
TransactionType.AdditionTransaction : (int) transData["TransType"] == 0 ? 
TransactionType.AdditionTransaction : TransactionType.SubtractionTransaction;
                    DateTime transDate = transData["TransDate"] is DBNull ? DateTime.Now : 
(DateTime) transData["TransDate"];
                    string transCategory = transData["TransCategory"] is DBNull ? string.Empty : 
transData["TransCategory"].ToString();
                    string transDescription = transData["TransDescription"] is DBNull ? string.Empty : 
transData["TransDescription"].ToString();
                    double transAmount = transData["TransAmount"] is DBNull ? 0 : 
(double)transData["TransAmount"];                     

                    if (transType == TransactionType.AdditionTransaction)
                        AddTransaction(transID, transAmount, transCategory, transDescription, transDate);

                    if (transType == TransactionType.SubtractionTransaction)
                        SubtractTransaction(transID, transAmount, transCategory, transDescription, transDate);
                }
            }

            return true;
        }

 This change required that the addition and subtraction routines were overloaded with a private method that took the transaction ID, the previous methods simply handed in 0 as a transaction id.

 

        private bool AddTransaction(int transID, double amount, string category, string description, 
DateTime transactionDate)
        {
            MoneyTransaction trans = new MoneyTransaction(transID, amount, category, description, 
transactionDate, TransactionType.AdditionTransaction);
            _History.Add(trans);

            _Balance += trans.TransactionAmount;

            return true;
        }
        public bool AddTransaction(double amount, string category, string description, DateTime transactionDate)
        {
            return AddTransaction(0, amount, category, description, transactionDate);
        }
        private bool SubtractTransaction(int transID, double amount, string category, string description, 
DateTime transactionDate)
        {
            MoneyTransaction trans = new MoneyTransaction(transID, amount, category, description, 
transactionDate, TransactionType.SubtractionTransaction);
            _History.Add(trans);

            _Balance -= trans.TransactionAmount;

            return true;
        }
        public bool SubtractTransaction(double amount, string category, string description, 
DateTime transactionDate)
        {
            return SubtractTransaction(0, amount, category, description, transactionDate);
        }

A quick run of all the tests confirms that we haven’t broken anything, you will also notice form the following screen shot that I changed the order in that the data is returned, and set the formatting on the account column, so that it matches the balance.

So next is the transaction addition

Advertisements

About Duncan Butler

Trying to be a very agile software developer, working in C# with Specflow, Nunit and Machine Specifications, and in the evening having fun with Ruby and Rails
This entry was posted in Projects. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s