Click here to Skip to main content
15,896,201 members
Articles / Desktop Programming / WPF

Catel - Part 4 of n: Unit testing with Catel

Rate me:
Please Sign up or sign in to vote.
4.55/5 (10 votes)
28 Jan 2011CPOL11 min read 49.5K   572   11  
This article explains how to write unit tests for MVVM using Catel.
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="TipOfTheDayData.cs" company="Catel development team">
//   Copyright (c) 2008 - 2011 Catel development team. All rights reserved.
// </copyright>
// <summary>
//   Class that shows a tip of the day.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Xml.Serialization;
using Catel.Runtime.Serialization;

namespace Catel.Windows.Data
{
    /// <summary>
    /// Class that shows a tip of the day.
    /// </summary>
    [XmlRoot("TipOfTheDay", Namespace = "http://schemas.catel.com/winfx/2010/TipOfTheDay")]
    public class TipOfTheDayData
    {
        #region Variables
        private ObservableCollection<TipOfTheDayItem> _tips = new ObservableCollection<TipOfTheDayItem>();
        private List<int> _tipsToShow = new List<int>();
        #endregion

        #region Constructor & destructor
        /// <summary>
        /// Initializes a new instance of the <see cref="TipOfTheDayData"/> class.
        /// </summary>
        public TipOfTheDayData()
        {
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets the list of tips.
        /// </summary>
        [XmlElement("Tip", typeof(TipOfTheDayItem))]
        public ObservableCollection<TipOfTheDayItem> Tips
        {
            get { return _tips; }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Loads a TipOfTheDay from a file.
        /// </summary>
        /// <returns>TipOfTheDay object.</returns>
        public static TipOfTheDayData Load()
        {
            TipOfTheDayData result = SerializationHelper.DeserializeXml<TipOfTheDayData>(PathHelper.FullTipOfTheDayPath, PathHelper.RelativeTipOfTheDayPath);
            result.UpdateToShowList();
            return result;
        }

        /// <summary>
        /// Saves the current instance of this data object.
        /// </summary>
        /// <returns>True if save was successful, otherwise false.</returns>
        public bool Save()
        {
            return SerializationHelper.SerializeXml(PathHelper.FullTipOfTheDayPath, this);
        }

        /// <summary>
        /// Updates the list that contains the to show tips.
        /// </summary>
        private void UpdateToShowList()
        {
            _tipsToShow.Clear();
            for (int i = 0; i < _tips.Count; i++)
            {
                _tipsToShow.Add(i);
            }
        }

        /// <summary>
        /// Gets the next tip index when the tips should occur randomly.
        /// </summary>
        /// <returns>Index of the next tip or -1 if there are no tips.</returns>
        public int GetNextTip()
        {
            if (_tipsToShow.Count <= 0)
            {
                UpdateToShowList();

                if (_tipsToShow.Count <= 0)
                {
                    return -1;
                }
            }

            // Get a random tip that is still in the tips to show
            Random random = new Random(DateTime.Now.Millisecond);
            int indexToShow = random.Next(_tipsToShow.Count - 1);
            int result = _tipsToShow[indexToShow];
            _tipsToShow.Remove(_tipsToShow[indexToShow]);
            return result;
        }
        #endregion
    }

    /// <summary>
    /// Class that represents a single TipOfTheDay element.
    /// </summary>
    public class TipOfTheDayItem : ICloneable, INotifyPropertyChanged
    {
        #region Variables
        private string _title = string.Empty;
        private string _description = string.Empty;
        #endregion

        #region Constructor & destructor
        /// <summary>
        /// Initializes a new instance of the <see cref="TipOfTheDayItem"/> class.
        /// </summary>
        public TipOfTheDayItem()
        {
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the title.
        /// </summary>
        [XmlElement("Title")]
        public string Title
        {
            get { return _title; }
            set
            {
                _title = value;
                OnPropertyChanged("Title");
            }
        }

        /// <summary>
        /// Gets or sets the description.
        /// </summary>
        [XmlElement("Description")]
        public string Description
        {
            get { return _description; }
            set
            {
                _description = value;
                OnPropertyChanged("Description");
            }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Clones the object
        /// </summary>
        /// <returns>New object</returns>
        public object Clone()
        {
            TipOfTheDayItem newObject = new TipOfTheDayItem();
            newObject.Title = Title;
            newObject.Description = Description;

            return newObject;
        }

        /// <summary>
        /// Called when a property has changed.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

        #region INotifyPropertyChanged Members
        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Software Developer
Netherlands Netherlands
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions