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 have a class that inherits from a generic class. The subclass has a method called "FindStuff" that calls the base class Find generic method.

I am trying to unit test a class that creates an instance of the subclass; I want to TypeMock the call to the FindStuff method. How in the world do I accomplish this?
asked by csustek (4k points)

9 Answers

0 votes
Hi,
An example would help, I am not sure I understand so I am guessing here.
If you want to mock FindStuff to return a fake result you could do something like this.
Mock mockedSubClass = MockManager.Mock(typeof(SubClass));
mockedSubClass.ExpectAndReturn("FindStuff",fakeResult);

When you want FindStuff to work and only Find to be mocked use:
Mock mockedSubClass = MockManager.Mock(typeof(SubClass));
mockedSubClass.ExpectAndReturn("Find",fakeResult);

More about mocking in the hiearchy in ourCTO's Blog.
answered by scott (32k points)
0 votes
Here is the parent class:
public class Repository<TDomainObject>
{
    public List<TDomainObject> Find<TIdentity>(
        ISelectionFactory<TIdentity> selectionFactory,
        IDomainObjectFactory<TDomainObject> domainObjectFactory,
        TIdentity identity)
    {
        List<TDomainObject> results = new List<TDomainObject>();

        using (DbCommand command = selectionFactory.ConstructSelectCommand(db, identity))
        {
            using (IDataReader rdr = db.ExecuteReader(command))
            {
                while (rdr.Read())
                {
                    results.Add(domainObjectFactory.Construct(rdr));
                }
            }
        }
        return results;
    }
}



Here is the class that I'm trying to unit test. I need to be able to mock the Find method of the parent class.
public class ConfigurationTypeRepository : Repository<ConfigurationType>
{
    public List<ConfigurationType> FindConfigurationTypes(System.Int32 ownerId)
    {
        ConfigurationTypeSelectionFactory selectionFactory = new ConfigurationTypeSelectionFactory();
        List<ConfigurationType> result;

        try
        {
            result = base.Find<System.Int32>(selectionFactory, domainObjectFactory, ownerId);
        }
        catch (SqlException ex)
        {
            bool rethrow = ExceptionPolicy.HandleException(ex, ExceptionPolicies.Model.ToString());
            if (rethrow)
            {
                throw;
            }
            else
            {
                result = null;
            }
        }

        return result;
    }
}
answered by csustek (4k points)
0 votes
Hi

What you need is to to use the CallBase property of the mock object
e.g

        [Test]
        public void TestDerived()
        {
            Mock mock = MockManager.Mock(typeof(ConfigurationTypeRepository));
            mock.CallBase.ExpectAndReturn("Find", FakeResult);
        }


This will mock Find and will return any desired value.
answered by ohad (35.4k points)
0 votes
Hi,
You don't really need to use CallBase, just remember that you have to mock the type that is calling the method and NOT the type that defines the method. In your case the type is ConfigurationTypeRepository.
answered by scott (32k points)
0 votes
When I try this, the Mock isn't working. When I step into the Find method, it still steps through the code rather than jump straight out.
answered by csustek (4k points)
0 votes
Hi
Can you please post your test here?
answered by ohad (35.4k points)
0 votes
Hi
Can you please post your test here?


Sure. Here is the code for the actual base class method I'm trying to execute:

        public List<TDomainObject> FindAll(
            ISelectionFactory selectionFactory,
            IDomainObjectFactory<TDomainObject> domainObjectFactory)
        {
            List<TDomainObject> results = new List<TDomainObject>();

            using (DbCommand command = selectionFactory.ConstructSelectCommand(_db))
            {
                using (IDataReader rdr = _db.ExecuteReader(command))
                {
                    while (rdr.Read())
                    {
                        results.Add(domainObjectFactory.Construct(rdr));
                    }
                }
            }
            return results;
        }


Here is the test:
        public void FindConfigurationTypesTest()
        {
            string databaseName = "Test";

            MockObject dbMock = MockManager.MockObject(typeof(SqlDatabase), Constructor.NotMocked, databaseName);
            Database db = (Database)dbMock.Object;
            Mock factoryMockCreateDatabase = MockManager.Mock(typeof(DatabaseFactory));
            factoryMockCreateDatabase.ExpectAndReturn("CreateDatabase", db, 1);

            RepositoryType type = RepositoryType.DBInstance;

            ConfigurationTypeRepository target = new ConfigurationTypeRepository(databaseName, type);

            int ownerId = 0;

            List<ConfigurationType> mockList = BuildConfigurationTypeList();
            List<ConfigurationType> expected = mockList;
            List<ConfigurationType> actual;

            MockObject mockSelectionFactory = MockManager.MockObject(typeof(ConfigurationTypeSelectionFactory));
            ConfigurationTypeSelectionFactory csf = (ConfigurationTypeSelectionFactory)mockSelectionFactory.Object;

            MockObject mockComponentFactory = MockManager.MockObject(typeof(ConfigurationTypeFactory));
            ConfigurationTypeFactory cf = (ConfigurationTypeFactory)mockComponentFactory.Object;

            Mock mock = MockManager.Mock(typeof(ConfigurationTypeRepository), true);
            mock.CallBase.ExpectAndReturn("FindAll", mockList).Args(csf, cf);

            actual = target.FindConfigurationTypes();

            Assert.IsNotNull(actual, "Null was returned");
            Assert.AreEqual(expected, actual, "TriadFinancial.ApplicationAdmin.Resource.DataAccess.Repositories.Core.Configurati" +
                    "onTypeRepository.FindConfigurationTypes did not return the expected value.");
        }


Let me know if you need any more information.[/code]
answered by csustek (4k points)
0 votes
Hi
The problem is that MockManager.Mock will mock the next instance of the type.
See the explanation here
All you have to do is move the the line
ConfigurationTypeRepository target = new ConfigurationTypeRepository(databaseName, type);

after the the line that mocks ConfigurationTypeRepository
So your test should looks like this:
        public void FindConfigurationTypesTest()
        {
            string databaseName = "Test";

            MockObject dbMock = MockManager.MockObject(typeof(SqlDatabase), Constructor.NotMocked, databaseName);
            Database db = (Database)dbMock.Object;
            Mock factoryMockCreateDatabase = MockManager.Mock(typeof(DatabaseFactory));
            factoryMockCreateDatabase.ExpectAndReturn("CreateDatabase", db, 1);

            RepositoryType type = RepositoryType.DBInstance;

            //wrong unless you use MockManager.MockAll()
            //ConfigurationTypeRepository target = new ConfigurationTypeRepository(databaseName, type);

            int ownerId = 0;

            List<ConfigurationType> mockList = BuildConfigurationTypeList();
            List<ConfigurationType> expected = mockList;
            List<ConfigurationType> actual;

            MockObject mockSelectionFactory = MockManager.MockObject(typeof(ConfigurationTypeSelectionFactory));
            ConfigurationTypeSelectionFactory csf = (ConfigurationTypeSelectionFactory)mockSelectionFactory.Object;

            MockObject mockComponentFactory = MockManager.MockObject(typeof(ConfigurationTypeFactory));
            ConfigurationTypeFactory cf = (ConfigurationTypeFactory)mockComponentFactory.Object;

            Mock mock = MockManager.Mock(typeof(ConfigurationTypeRepository), true);
            mock.CallBase.ExpectAndReturn("FindAll", mockList).Args(csf, cf);
            //This should work
            ConfigurationTypeRepository target = new ConfigurationTypeRepository(databaseName, type);

            actual = target.FindConfigurationTypes();

            Assert.IsNotNull(actual, "Null was returned");
            Assert.AreEqual(expected, actual, "TriadFinancial.ApplicationAdmin.Resource.DataAccess.Repositories.Core.Configurati" +
                    "onTypeRepository.FindConfigurationTypes did not return the expected value.");
        }


Another option is to use MockManager.MockAll method. This will mock all instances of mocked type.
Hope it helps.
answered by ohad (35.4k points)
0 votes
I made your change, and removed the Args from the ExpectAndReturn, and I'm getting a green light. Your suggestion makes perfect sense. Thanks!
answered by csustek (4k points)
...