Click here to Skip to main content
15,881,424 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am exploring TDD and state transition testing.
I have a hard time getting my head around how this test can be written before the code. In an attempt to understand I started to write the actual method first and then the test.
But I want to do it as TDD not reverse engineering.Could someone please help me?

I really want to grasp TDD.Can you show an example for how a test case could look for the method ChangeMode?

About the method:

The method ChangeMode is supposed to return string s which is: currentDate || currentTime depending on what state the clock is currently set to (Time or date). The class also has a set method which sets the state and fetches the data needed depending on state from two other classes ( time & date)

I have value to keep track of what enum-value is currently selected. I have no UI.

To clarify: change Mode has two states, currentDate, CurrentTime. Depending on which is selected the method returns a string.

I test in visual studio with the nuget NUnit testadapter.


C#
public string changeMode()
    {
        string s; 

        States value; //Uncertain how this variable holding the selected enum value should look

      if (value == States.DisplayDate)
      {
          s = theDate.showDate();
          return s; 
      }

      if (value == States.DisplayTime)
      {
          s = theTime.ShowTime();
          return s;
      }

      else MessageBox.Show("Error, no state is selected for changeMode"); 
        return null; 
    }

For the Testcase I have so far came up with :

C#
[TestCase]
{
bool state = clockobj.changeMode();  //This is where I do not know how to write the test.
Assert.AreEqual(true, state);        // ofcourse this code will never compile.
Posted
Updated 15-Jan-15 0:52am
v4
Comments
Rob Philpott 15-Jan-15 17:03pm    
Did you figure this out? The answer is going to be quite long and I'm heading to bed shortly but can answer tomorrow if you like.

1 solution

I’m not an expert on this, so I have posted what follows as a self -help and learning exercise for the two of us. This is my take on the problem.

As it stands, your changeMode method is dependent upon three other classes, theDate, theTime and MessageBox. It has a dual purpose, to return a string and, in certain circumstances, to display an error message. I’d remove the MessageBox and do the error checking on the value returned from the method elsewhere. This would leave the changeMode method with just one task to perform and, consequently, one task to be tested.

The method can be further refined by using a switch statement in order both to remove multiple exit paths within the method and to have a single return statement at the end. It’s easier to debug when there is only one way out of a method.

To test the method, you need to create fake theDate and fake theTime classes. The creation of fake objects is facilitated by having them implement an Interface that they share with the class they are faking.

The showDate method should return the same date on every occasion it is called and the showTime method should return the same time on every occasion. This is because unit test should be self contained, exactly repeatable, run entirely in memory and be independent of external objects such as a database, system clock and random number generators. One final point, the States variable is private. This needs to be protected in order to be able to access it for testing. The example below just has the one test but there needs to be a further two, testing for both StateValue=null and StateValue=State.DisplayTime


”C#”
namespace UnitTestProject1
{
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    public interface ITheTime
    {
        #region Public Methods and Operators

        string ShowTime();

        #endregion
    }

    public interface ITheDate
    {
        #region Public Methods and Operators

        string ShowDate();

        #endregion
    }

    public class ClockObject
    {
        #region Constants and Fields

        protected States StateValue;

        protected ITheDate theDate;

        protected ITheTime theTime;

        #endregion

        #region Enums

        protected enum States
        {
            DisplayDate,

            DisplayTime
        }

        #endregion

        #region Public Methods and Operators

        public string changeMode()
        {
            string s;
            switch (this.StateValue)
            {
                case States.DisplayDate:
                {
                    s = this.theDate.ShowDate();
                    break;
                }
                case States.DisplayTime:
                {
                    s = this.theTime.ShowTime();
                    break;
                }
                default:
                {
                    s = null;
                    break;
                }
            }
            return s;
        }

        #endregion
    }

    public class TheDateStub : ITheDate
    {
        #region Public Methods and Operators

        public string ShowDate()
        {
            return "ShowDate";
        }

        #endregion
    }

    public class TheTimeStub : ITheTime
    {
        #region Public Methods and Operators

        public string ShowTime()
        {
            return "ShowTime";
        }

        #endregion
    }

    [TestClass]
    public class UnitTest1
    {
        #region Public Methods and Operators

        [TestMethod]
        public void changeModeReturnsDateStringWhenStateValueEqualsDisplayDate()
        {
            var mockClockObject = new MockClockObject();
            string displayDate = mockClockObject.changeMode();
            Assert.AreEqual(displayDate, "ShowDate");
        }

        #endregion

        private class MockClockObject : ClockObject
        {
            #region Constructors and Destructors

            public MockClockObject()
            {
                this.StateValue = States.DisplayDate;
                this.theDate = new TheDateStub();
                this.theTime = new TheTimeStub();
            }

            #endregion
        }
    }
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900