chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
I spent a couple of days evaluating TypeMock.NET using simple examples. When I went on to try to apply it to a class in our real code I could not see how to proceed. Rather than send you the actual code, I created the code at the foot of this email to illustrate the essence of the issues.

The pages in our application are represented by the ConcretePage class which is derived from AbstractPage and BasePage. The constructors of all of these pages requires two arguments which I have represented as a PlaceHolder and a PageControl. However, when these classes are instantiated their instance variable are not initialised. So in the AbstractPage.Initialise method the aPageControl.Navigator is null. Also the Controls collection will also be null.

I am probably missing some key concept but I cannot see how to proceed and I cannot see how the examples relate to this (more or less) real life scenario.

Any assistance would be appreciated.

Thanks

John

PS I'm sorry this is a bit long winded but I want to make sure I can get TypeMock.NET working on a more realistic example before making any recommendations about using it.

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.Data;
using NUnit.Framework;
using TypeMock;

namespace SimpleTypeMockExamples
{
    public abstract class BasePage
    {
        private List<System.Web.UI.Control> _Controls = new List<System.Web.UI.Control>();

        public List<System.Web.UI.Control> Controls
        {
            get { return _Controls; }
        }

        protected virtual void Initialise(PlaceHolder aPlaceHolder, PageControl aPageControl)
        {
            foreach (System.Web.UI.Control ctrl in aPageControl.Controls)
            {
                // Do something with the controls list - here I've just added them to another collection.
                _Controls.Add(ctrl);
            }

            // Do other things with aPlaceHolder

        }
    }

    public abstract class AbstractPage : BasePage
    {
        protected override void Initialise(PlaceHolder aPlaceHolder, PageControl aPageControl)
        {
            aPageControl.Navigator.OnPageReloadHandler += new PageReloadHandler(Navigator_OnPageReloadHandler);
            base.Initialise(aPlaceHolder, aPageControl);
        }

        void Navigator_OnPageReloadHandler(string message)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    }

    public class ConcretePage : AbstractPage
    {
        public ConcretePage(PlaceHolder aPlaceHolder, PageControl aPageControl)
      {
            Initialise(aPlaceHolder, aPageControl);
      }
    }

    public delegate void PageReloadHandler(string message); 

    public class Navigator
    {
        public event SimpleTypeMockExamples.PageReloadHandler OnPageReloadHandler;
    }

    public class PageControl
    {
        private const int pageId = 1234;
        private List<System.Web.UI.Control> _Controls = null;
        private Navigator _Navigator;

        public Navigator Navigator
        {
            get { return _Navigator; }
            set { _Navigator = value; }
        }

        public List<System.Web.UI.Control> Controls
        {
            get { return _Controls; }
        }

        public void InitialiseControlsFromDatabase()
        {
            _Controls = DataLayer.GetControls(pageId);
        }

    }

    public class DataLayer
    {
        //
        // Dummy class that replaces the class(es) that access the database
        //
        public static List<System.Web.UI.Control> GetControls(int pageId)
        {
            // This method would read the page configurations containing
            // controls and their layouts as well as database views to 
            // populate the controls. 
            List<System.Web.UI.Control> controlsList = new List<System.Web.UI.Control>();
            //
            // Read the database and populate the controlsList
            //
            return controlsList;
        }
    }

    [TestFixture]
    class PageClassesTest
    {
        [Test]
        public void TestConstruction()
        {
            MockManager.Init();

            Mock mockNavigator = MockManager.Mock(typeof(Navigator));
            mockNavigator.ExpectAddEvent("OnPageReloadHandler");

            PageControl aPageControl = new PageControl();
            PlaceHolder aPlaceHolder = new PlaceHolder();

            ConcretePage dummyPage = new ConcretePage(aPlaceHolder, aPageControl);

            MockManager.Verify();
        }
    }

}
asked by johnkirby (1.6k points)

3 Answers

0 votes
Hi,
When you mock Navigator, you are telling TypeMock to mock the next created instance of Navigator.
As this instance is never created (there is no new Navigator())you will fail,

What you have to do is create a MockObject of Navigator and then set the PageControl.Navigator property to the Mocked Object.
Here is how:
 MockObject mockNavigator = MockManager.MockObject(typeof(Navigator));
// set our mock object to be our navigator
PageControl aPageControl = new PageControl();
aPageControl.Navigator = (Navigator) mockNavigator.Object;


The same rational applies to the Controls property. We will need to give it a fake implementation. Suppose we want an empty list.
In this case we cannot set the Controls (it is private) so we will mock the Controls property to return our fake list.
Here is how:
// mock the PageControl, because PageControl is a concrete type
// all methods will run as normal unless we say otherwise
MockObject mockPageControl = MockManager.MockObject(typeof(PageControl));

// our fake controls
List<System.Web.UI.Control> fakeControls = new List<System.Web.UI.Control>();
// inject it into our system
mockPageControl.ExpectGetAlways("Controls", fakeControls);


So our whole test looks like this:
[Test]
public void TestConstruction()
{
   // check that we register the event
   MockObject mockNavigator = MockManager.MockObject(typeof(Navigator));
   mockNavigator.ExpectAddEvent("OnPageReloadHandler");

   // create a PageControl we are going to stub the Control property
   MockObject mockPageControl = MockManager.MockObject(typeof(PageControl));
   PageControl aPageControl = (PageControl)mockPageControl.Object;

   // inject our mock navigator
   aPageControl.Navigator = (Navigator) mockNavigator.Object;

   // our fake controls
   List<System.Web.UI.Control> fakeControls = new List<System.Web.UI.Control>();
   // inject them into our system
   mockPageControl.ExpectGetAlways("Controls", fakeControls);

  PlaceHolder aPlaceHolder = new PlaceHolder();

  ConcretePage dummyPage = new ConcretePage(aPlaceHolder, aPageControl);

   MockManager.Verify();
}


:idea: Now we can fire the event to see if everything works.
Change the second line to:
MockedEvent handler = mockNavigator.ExpectAddEvent("OnPageReloadHandler");

and you can fire the event by using
handler.Fire("message");

You will see your exception in OnPageReloadHandler begin throw!! Super Cool 8)
answered by scott (32k points)
0 votes
There are other way which you can inject the Controls into PageControl

:arrow: Mock the Controls property like in the previous post.

:arrow: Use ObjectStateto change the field
PageControl aPageControl = new PageControl();
ObjectState.SetField(aPageControl, "_Controls", fakeControls);


:arrow: Mock DataLayer.GetControls and call InitialiseControlsFromDatabase()
Mock dataLayerMock = MockManager.Mock(typeof (DataLayer));
dataLayerMock.ExpectAndReturn("GetControls", fakeControls);

PageControl aPageControl = new PageControl();
aPageControl.InitialiseControlsFromDatabase();


8)
answered by scott (32k points)
0 votes
Thanks this looks good! I'll have a look though I might have more questions.

:)

John
answered by johnkirby (1.6k points)
...