This is a migrated thread and some comments may be shown as answers.

How to mock "new instance"

6 Answers 188 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Yi
Top achievements
Rank 1
Yi asked on 22 Jan 2013, 08:41 AM
Hi There, 

Can anyone give me a hand of how to mock internal new instance in my unit test? my method like below:

        public List<Driver> SearchByDriverName(string driverName, bool? status)
        {
            IDriverDAC driverDAC = new DriverDAC();
            List<Driver> drivers = new List<Driver>();
            drivers = driverDAC.SearchByDriverName(driverName, status);
            return drivers;
        }

here i want to test this method, the first thing i need to do is mock the DriverDAC (mock driverDAC.SearchByDriverName 
method), but the issue is the DriverDAC
is not injected into this class, it is created by new instance, so i can not mock & by pass the SearchByDriverName method,
can anybody give me a light of how to do it? understand it is better to use DI to inject the class,
but due to some special reason by user, we can not change the design structure now.

Thanks!

Suyi


6 Answers, 1 is accepted

Sort by
0
Chris
Top achievements
Rank 1
answered on 22 Jan 2013, 01:11 PM
To the best of my knowledge that isn't possible.  Since there is nothing for JustMock to intercept easily.  This is where Inversion of Control and Dependency Injection come in to "save the day".  I would suggest looking into a tool such as StructureMap, Ninject, or Unity to handle your inversion of control/DI or create a custom factory method (for all of your objects that you will call new on) and then you can mock the factory methods to return whatever instance you want to have returned.(thereby mocking the new in a roundabout way)

Of course the other option is the simply pass the object in as a method parameter, then you aren't newing it there.....
0
Kaloyan
Telerik team
answered on 22 Jan 2013, 04:09 PM
Hi Yi Su,

Thank you for contacting Telerik support.

A solution to your issue could be the using of JustMocks Future Mocking. You could try the following approach:
var mockedDriverDAC = Mock.Create<DriverDAC>();
 
var desiredDriverName = ...;
var desiredStatus = ...;

var desiredCollection = ...;

Mock.Arrange(() => mockedDriverDAC.SearchByDriverName(desiredDriverName, desiredStatus)).IgnoreInstance().ReturnsCollection(desiredCollection);

Having this setup in your test will arrange the "SearchByDriverName" method to return your desired collection, no matter the instance.

I hope this helps.

Greetings,
Kaloyan
the Telerik team
Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
0
Yi
Top achievements
Rank 1
answered on 24 Jan 2013, 09:14 AM
Hi Kaloyan, 

Thanks for your reply, but i am still can not make my test working, do justmock have any limitation of partial class? 
why i ask this because i write a example and can make it work but when i move to my business class, i found it is not working, 
i guess maybe it caused by i have 2 same naming partial class both called "DriverDAC" in my project,
so at the times when i trying to mock DriverDAC, it is not working, parse my code as below 

1.My Unit test class

using STB.EP.RBS.Business;
using System.Collections.Generic;
using System;
using STB.EP.RBS.Data;
using STB.EP.RBS.Business.Entities;
//using Microsoft.SharePoint;
using Telerik.JustMock;
 
#if !NUNIT
using Microsoft.VisualStudio.TestTools.UnitTesting;
using AssertionException = Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException;
#else
using NUnit.Framework;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
using System.Xml;
#endif
 
 
namespace STB.EP.RBS.Test.TransportBooking
{
    /**
     * This is a test class for DriverComponentTest and is intended
     * to contain all DriverComponentTest Unit Tests
     */
    [TestClass()]
    public class DriverComponentTest
    {
        List<Driver> driverList;
        DriverComponent dc;
        /// <summary>
        /// Initialize parameters and method
        /// </summary>
        [TestInitialize]
        public void Initialize()
        {
            driverList = new List<Driver>();
            Driver driver = new Driver();
            driver.DriverId = 1;
            driver.DriverName = "Driver 1";
            driver.DrivingLicenses = "SGXXXXX";
            driver.MobileNumber = "12345678";
            driver.Status = true;
            driver.CreatedBy = "admin";
            driver.CreatedOn = new DateTime();
            driver.Description = "Driver 1";
            driverList.Add(driver);
 
            dc = new DriverComponent();
        }       
         
        [TestMethod()]
        public void testSearchByDriverName()
        {
             
            var driverDAC = Mock.Create<STB.EP.RBS.Data.DriverDAC>();
            Mock.Arrange(() => driverDAC.CheckExistDriver(Arg.IsAny<string>())).IgnoreInstance().Returns(driverList);
            Assert.AreEqual(driverList, new DriverDAC().CheckExistDriver(""));
              
        }
 
        [TestMethod()]
        public void testExample()
        {
            var u = Mock.Create<SubUnitTest>();
            Mock.Arrange(() => u.getMessage(Arg.IsAny<string>())).IgnoreInstance().Returns("123");
            Assert.AreEqual("123", new unitTest().getStr("test"));
        }
 
        public class unitTest
        {
            public string getStr(string test)
            {
                SubUnitTest sub = new SubUnitTest();
                return sub.getMessage(test);
            }
        }
 
        public class SubUnitTest
        {
            public string getMessage(String str)
            {
                return str;
            }
        }
    }

2.Mocking class of "DriverDAC"

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;
using STB.EP.RBS.Business.Entities;
 
 
namespace STB.EP.RBS.Data
{
    /// <summary>
    /// Driver data access component for customization.
    /// </summary>
    public partial class DriverDAC : DataAccessComponent
    {
         
        public virtual List<Driver> CheckExistDriver(string driverName)
        {
            DbCommand dbCommand = ConnectionHelper.DbConnection.GetStoredProcCommand(Constants.PRC_Driver_CheckExistDriver);
            List<Driver> results = new List<Driver>();
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "DriverName", DbType.String, driverName);
            using (IDataReader dr = ConnectionHelper.DbConnection.ExecuteReader(dbCommand))
            {
                while (dr.Read())
                {
                    results.Add(GetDataRow(dr));
                }
            }
            return results;
 
        }      
    }
}

2.1 Another Mocking class , same name as "DriverDAC"

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;
using STB.EP.RBS.Business.Entities;
 
 
namespace STB.EP.RBS.Data
{
    public partial class DriverDAC : DataAccessComponent
    {
        /// <summary>
        /// Inserts a new row in the Driver table.
        /// </summary>
        /// <param name="roomBooking">A Driver object.</param>
        /// <returns>An updated Driver object.</returns>
        public  Driver Create( Driver driver)
        {
            DbCommand dbCommand = ConnectionHelper.DbConnection.GetStoredProcCommand(Constants.PRC_Driver_Insert);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "DriverName", DbType.String, driver.DriverName);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "DrivingLicenses", DbType.String, driver.DrivingLicenses);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "MobileNumber", DbType.String, driver.MobileNumber);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "Status", DbType.Boolean, driver.Status);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "CreatedBy", DbType.String, driver.CreatedBy);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "ModifiedBy", DbType.String, driver.ModifiedBy);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "Description", DbType.String, driver.Description);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "OldDriverId", DbType.Guid, driver.OldDriverId);
         
            object obj = ConnectionHelper.DbConnection.ExecuteScalar(dbCommand);
            driver.DriverId =  Convert.ToInt16(obj);
            return driver;
        }
     
        /// <summary>
        /// Updates an existing row in the Driver table.
        /// </summary>
        /// <param name="driver">A Driver entity object.</param>
        public  void UpdateById( Driver driver)
        {
            DbCommand dbCommand = ConnectionHelper.DbConnection.GetStoredProcCommand(Constants.PRC_Driver_Update);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "DriverId", DbType.Int16, driver.DriverId);
             
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "DriverName", DbType.String, driver.DriverName);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "DrivingLicenses", DbType.String, driver.DrivingLicenses);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "MobileNumber", DbType.String, driver.MobileNumber);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "Status", DbType.Boolean, driver.Status);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "CreatedBy", DbType.String, driver.CreatedBy);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "ModifiedBy", DbType.String, driver.ModifiedBy);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "Description", DbType.String, driver.Description);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "OldDriverId", DbType.Guid, driver.OldDriverId);
         
            object obj = ConnectionHelper.DbConnection.ExecuteNonQuery(dbCommand);
        }
     
        /// <summary>
        /// Conditionally deletes one or more rows in the Driver table.
        /// </summary>
        /// <param name="driverId">A driverId value.</param>
        public  void DeleteById( int driverId)
        {
            DbCommand dbCommand = ConnectionHelper.DbConnection.GetStoredProcCommand(Constants.PRC_Driver_Delete);
            ConnectionHelper.DbConnection.AddInParameter(dbCommand, "DriverId", DbType.Int16, driverId);
         
            object obj = ConnectionHelper.DbConnection.ExecuteNonQuery(dbCommand);
        }
     
        /// <summary>
        /// Returns a row from the Driver table.
        /// </summary>
        /// <param name="driverId">A driverId value.</param>
        /// <param name="archivedData">Select data from archival database.</param>
        /// <returns>A RoomBooking object with data populated from the database.</returns>
        public Driver SelectById( int driverId,bool archivedData)
        {
            Database dbConnection = (archivedData) ? ConnectionHelper.ArchivalDbConnection : ConnectionHelper.DbConnection;
            DbCommand dbCommand = dbConnection.GetStoredProcCommand(Constants.PRC_Driver_Select);
            dbConnection.AddInParameter(dbCommand, "DriverId", DbType.Int16, driverId);
            Driver driver = null;
            using (IDataReader dr = dbConnection.ExecuteReader(dbCommand))
            {
                while (dr.Read())
                {
                    driver = GetDataRow(dr);
                    break;
                }
            }
            return driver;
        }
     
        /// <summary>
        /// Returns multi row from the Driver table based on search critiria.
        /// </summary>
        /// <param name="driver">A Driver entity object.</param>
        /// <param name="archivedData">Select data from archival database.</param>
        /// <returns>A list of Driver object with data populated from the database.</returns>
        public  List<Driver> Search(Driver driver,bool archivedData)
        {
            Database dbConnection = (archivedData) ? ConnectionHelper.ArchivalDbConnection : ConnectionHelper.DbConnection;
            DbCommand dbCommand = dbConnection.GetStoredProcCommand(Constants.PRC_Driver_Search);
            dbConnection.AddInParameter(dbCommand, "DriverName", DbType.String, driver.DriverName);
            dbConnection.AddInParameter(dbCommand, "DrivingLicenses", DbType.String, driver.DrivingLicenses);
            dbConnection.AddInParameter(dbCommand, "MobileNumber", DbType.String, driver.MobileNumber);
            dbConnection.AddInParameter(dbCommand, "Status", DbType.Boolean, driver.Status);
            dbConnection.AddInParameter(dbCommand, "CreatedBy", DbType.String, driver.CreatedBy);
            dbConnection.AddInParameter(dbCommand, "CreatedOn", DbType.DateTime, driver.CreatedOn);
            dbConnection.AddInParameter(dbCommand, "ModifiedBy", DbType.String, driver.ModifiedBy);
            dbConnection.AddInParameter(dbCommand, "ModifiedOn", DbType.DateTime, driver.ModifiedOn);
            dbConnection.AddInParameter(dbCommand, "Description", DbType.String, driver.Description);
            dbConnection.AddInParameter(dbCommand, "OldDriverId", DbType.Guid, driver.OldDriverId);
         
            List<Driver> results = new List<Driver>();
            using (IDataReader dr = dbConnection.ExecuteReader(dbCommand))
            {
                while (dr.Read())
                {
                    results.Add(GetDataRow(dr));
                }
            }
            return results;
        }
     
        /// <summary>
        /// Returns a converted  Driver object from from the selected data row.
        /// </summary>
        /// <param name=" dr">A data row.</param>
        /// <returns>A Driver object with data populated from the database.</returns>
        private Driver GetDataRow(IDataReader dr)
        {
            // Create a new Driver
            Driver driver = new Driver();
 
            // Read values.
 
            driver.DriverId = base.GetDataValue<Int16>(dr, "DriverId");
            driver.DriverName = base.GetDataValue<string>(dr, "DriverName");
            driver.DrivingLicenses = base.GetDataValue<string>(dr, "DrivingLicenses");
            driver.MobileNumber = base.GetDataValue<string>(dr, "MobileNumber");
            driver.Status = base.GetDataValue<bool>(dr, "Status");
            driver.CreatedBy = base.GetDataValue<string>(dr, "CreatedBy");
            driver.CreatedOn = base.GetDataValue<DateTime>(dr, "CreatedOn");
            driver.ModifiedBy = base.GetDataValue<string>(dr, "ModifiedBy");
            driver.ModifiedOn = base.GetDataValue<DateTime>(dr, "ModifiedOn");
            driver.Description = base.GetDataValue<string>(dr, "Description");
            driver.OldDriverId = base.GetDataValue<Guid>(dr, "OldDriverId");
            return driver;
        }
    }
}

Kindly note, i can make testExample() working but testSearchByDriverName() still got issue

0
Yi
Top achievements
Rank 1
answered on 24 Jan 2013, 09:19 AM
By the way, one more interesting thing is if i put "virtual" before my method "CheckExistDriver" , below test is working, but if i remove the virtual, it is not working, do not know why

[TestMethod()]
public void testSearchByDriverName()
{           
    var driverDAC = Mock.Create<STB.EP.RBS.Data.DriverDAC>();
    Mock.Arrange(() => driverDAC.CheckExistDriver(Arg.IsAny<string>())).IgnoreInstance().Returns(driverList);
    Assert.AreEqual(driverList, driverDAC.CheckExistDriver(""));            
}
 
0
Yi
Top achievements
Rank 1
answered on 25 Jan 2013, 04:42 AM
I feel so confuse of Justmock, is JustMock 2012.3.1220.42 a stable version?
when i trying to run my test script (as parsed above), sometimes i can pass the test, 
sometimes i get failed, i 100% ensure there is no code changes, same code but get different result, it is going to make 
me upset. 
0
Kaloyan
Telerik team
answered on 28 Jan 2013, 01:54 PM
Hi again Yi Su,

To help you further on the matter, I would suggest couple of thing you could try:
  1. In order to arrange the returning of collections with JustMock, I would recommend the using of "ReturnsCollection()" method instead of "Returns()". This should fix the issue you are experiencing with the "testSearchByDriverName()" method.
  2. If the previous step does not solve the matter, I would ask, if possible, to send is the entire project for further investigation. Doing so will let us debug it on our side and provide the proper solution to your case. However, if this is not doable, I would require some additional information about your environment(What is the exact version of the Visual Studio you are using?) and about the exception being thrown by the failing test method.

Also, I should say that we have just released the Q3 SP2 of JustMock and I would recommend you trying it out. It contains a lot of bug fixes and improvements that could be checked here.

Thank you for the patience in advance. Please, contact us again if you need further assistance.

All the best,
Kaloyan
the Telerik team
Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
Tags
General Discussions
Asked by
Yi
Top achievements
Rank 1
Answers by
Chris
Top achievements
Rank 1
Kaloyan
Telerik team
Yi
Top achievements
Rank 1
Share this question
or