Welcome to Typemock Answers. Here you can ask and receive answers from other community members. And if you liked or disliked an answer or thread: react with an up- or downvote Enjoy!

abstract classes

0 votes
Hi for one more time :D a new century on TDD now begins thnks to your libary (evrything runs ok)

I have another question
Suppose i have a class-->Class2 that inherits Class1 and im doing the following
MockManager.Init(true);
Mock mock=MockManager.Mock(typeof(Class1),false);
mock.ExpectCall("Reload");
new Class2().Reload();
Assert.AreEqual(1,MockManager.CalledCounter("Class1","Reload");


the above call fails . is that the expected behaviour. I was expecting that code not to fail because Class2 inherits Class1
asked Jan 31, 2005 by tolisss (3,660 points)

5 Answers

0 votes
Hi for one more time :D a new century on TDD now begins thnks to your libary (evrything runs ok)

I am glad :D
I have another question
Suppose i have a class-->Class2 that inherits Class1 and im doing the following
...
the above call fails . is that the expected behaviour. I was expecting that code not to fail because Class2 inherits Class1

Well, this is the expected behaviour. TypeMock checks the actuall class that called the method, this is because of a problem of behaviour when the base method is mocked in 2 classes that extend the same base class , or when both the base and derived classes mock the same method. Do you have any ideas of how you would expect the library to work? We are always welcome to your input and if you have a better idea, we will see how to incorporate it in the library.
answered Jan 31, 2005 by scott (29,080 points)
0 votes
Still some confused on how exactly things works. let be describe.
Basically im owrikng on a project that is heavilly depended on XPO(DevExpress)
The code above was some like this
public class MainClass:XPBaseObject
   {
      [Key(true)]
      public int I
      {
         get { return i; }
         set { i = value; }
      }

      private int i = 0;
   }
   [TestFixture]
   public class ClassFixture
   {
      private Mock stoiheioMock;

      [Test]
      public void MethodName()
      {
         MockManager.Init(true);
         Mock mock = MockManager.Mock(typeof(MainClass),false);

            MainClass mainClass=new MainClass();
            mainClass.Save();
            mainClass.Save();

Assert.AreEqual(2, mock.GetCallCount("Save"));

that passes ok
but when u replace the XPBaseObject with another abstract class that inherits XPbaseObject then u should do

Assert.AreEqual(2, mock.GetCallCount("Save"));

in order not to fail

Also i have some more questions
1)Does the Mock.GetCallCount method works for properties also? It will be most usefull if it was
2)How to now to which value a property is set
answered Feb 1, 2005 by tolisss (3,660 points)
0 votes
but when u replace the XPBaseObject with another abstract class that inherits XPbaseObject then u should do

Assert.AreEqual(2, mock.GetCallCount("Save"));

in order not to fail

Please explain. All you are doing is changing XPBaseObject to another class and the same code doesn't work?
Also i have some more questions
1)Does the Mock.GetCallCount method works for properties also? It will be most usefull if it was

Just add "set_" or "get_" to the property name, for example to know that property Value was set twice and gotten (get) 3 times do
Assert.AreEqual(2, mock.GetCallCount("set_Value"));
Assert.AreEqual(3, mock.GetCallCount("get_Value"));

Although perhaps helper methods will make it easier to do. Should I add this as a feature request?
2)How to now to which value a property is set

I am not sure that I understand the question but in testing you can do two things:
1. actually test the Property:
Assert.AreEqual(2,mainClass.I);

2. make sure that an expected value was set
mock.ExpectSet("I").Args(2);
answered Feb 1, 2005 by scott (29,080 points)
0 votes
Please explain. All you are doing is changing XPBaseObject to another class and the same code doesn't work?

using System;
using System.Collections;
using System.ComponentModel;
using DevExpress.Xpo;
using DevExpress.Xpo.Metadata;
using NUnit.Framework;
using WM.Helpers;


using TypeMock;
using WM.Helpers.Fixtures;

namespace MCH.Fixtures
{
   
   public class BaseClass
   {
      public BaseClass()
      {
         //
         // TODO: Add constructor logic here
         //
      }

      public void Save()
      {
         
      }
   }
   public class MainClass:DBObject
   {
      [Key(true)]
      public int I
      {
         get { return i; }
         set { i = value; }
      }

      private int i = 0;
   }
   public class MainClass1:XPBaseObject
   {
      [Key(true)]
      public int I
      {
         get { return i; }
         set { i = value; }
      }

      private int i = 0;
   }
   [TestFixture]
   public class ClassFixture
   {
      private Mock stoiheioMock;

      [Test]
      public void MethodFail()
      {
         MockManager.Init(true);
         Mock mock = MockManager.Mock(typeof(MainClass),false);

         MainClass mainClass=new MainClass();
         mainClass.Save();


         Assert.AreEqual(1, mock.GetCallCount("Save"));

      }
      [Test]
      public void MethodPass()
      {
         MockManager.Init(true);
         Mock mock = MockManager.Mock(typeof(MainClass1),false);

         MainClass1 mainClass=new MainClass1();
         mainClass.Save();


         Assert.AreEqual(1, mock.GetCallCount("Save"));

      }
   }
}

   /// <summary>
   /// Override errors to provide class constrains b4 save
   /// </summary>
[NonPersistent, MemberDesignTimeVisibility(false)]
public abstract class DBObject:XPBaseObject,IChanged,IDataErrorInfo,ICloneable
{
   private bool isChanged = false;
   private bool isDeleted;
   private DalErrorProvider dalErrorProvider;
      

   public DBObject(Session session, XPClassInfo classInfo) : base(session, classInfo)
   {
   }

   public DBObject(Session session) : base(session)
   {
      dalErrorProvider = new DalErrorProvider(this);
      base.Changed +=new ObjectChangeEventHandler(DBObject_Changed);
   }
      
      
   public DBObject()
   {
      dalErrorProvider = new DalErrorProvider(this);
   }

   protected override void BeginEdit()
   {
   }

   protected override void EndEdit()
   {
   }

   protected override void CancelEdit()
   {
   }
   protected override void AfterLoad()
   {
      base.AfterLoad();
      isChanged=false;
   }
   /// <summary>
   /// u should overidde this method allowind first the base method to run and put your constrains here
   /// </summary>
   /// <returns>true if dalErrorProvider.NoteError.Length</returns>
   public virtual bool  errors()
   {
      dalErrorProvider.ClearErrors();
            
      return Convert.ToBoolean(dalErrorProvider.NoteError.Length);
   }
   public override void Save()
   {
      if (isDeleted)
      {
         base.Save();
      }
      else
      {
         if (!errors())
         {
            base.Save();
            isChanged = false;
         }
         else
            throw new DALException(dalErrorProvider.NoteError, GetType());
      }
   }

   public override void Delete()
   {
      base.Delete();
      isDeleted=true;
   }

   [NonPersistent]
   public bool IsChanged
   {
      get { return isChanged; }
      set { isChanged=value; }
   }

   private void DBObject_Changed(object sender, ObjectChangeEventArgs args)
   {
      isChanged = true;
   }
   #region IDataErrorInfo Members

      
   public string this[string columnName]
   {
      get
      {
         return dalErrorProvider.GetColumnError(columnName);
      }
      set
      {
         dalErrorProvider.SetColumnError(columnName,value);
      }
   }

   public string Error
   {
      get { return dalErrorProvider.NoteError; }
   }

   #endregion

   public object Clone()
   {
      return this.MemberwiseClone();
   }
}
public class DalErrorProvider
{
   private Hashtable propertyErrors = new Hashtable();
   private string noteError = "";
   private XPBaseObject xPBaseObject;

   public DalErrorProvider(XPBaseObject xPBaseObject)
&nb
answered Feb 1, 2005 by tolisss (3,660 points)
0 votes
public class MainClass:DBObject
{
}
public class MainClass1:XPBaseObject
}
[TestFixture]
public class ClassFixture
{
   [Test]
   public void MethodFail()
   {
      MockManager.Init(true);
      Mock mock = MockManager.Mock(typeof(MainClass),false);

      MainClass mainClass=new MainClass();
      mainClass.Save();

      Assert.AreEqual(1, mock.GetCallCount("Save"));

   }
}

public abstract class DBObject:XPBaseObject,IChanged,IDataErrorInfo,ICloneable
{
   public override void Save()
   {
      base.Save();
   }

}


I have cut down the code so that we can see that DBObject.Save() calls base.Save(), this is calculated as DBObject calling Save() twice as the object that calls the base.Save() is still DBObject.
Normally this will be used in mocks, so if you mock DBObject.Save() it won't call base.Save() so you have no problem.
If you think that this might be wrong behaviour and that when collecting calls it should collect calls of the actuall object it is defined in; This will mean that if DBObject doesn't override the Save(), then any call to DBObject.Save() will always be calculated as XPBaseObject Save() (as it actually calls the base).

A Better behaviour would probrably be, that if DBObject implements the Save() then only that Save() should be counted, I will see if we can change the behaviour but previously this check lead to performace problems. Hope this helps
answered Feb 1, 2005 by scott (29,080 points)
...