Is Mocking able to replace functionality wrapped inside a method?

c#, moq, typemock, unit-testing

Solution

Although you're currently use Moq I think that the functionality you're looking for cannot be achived without dependency injection unless you use Typemock Isolator (Disclaimer - I worked at Typemock).

Isolator has a feature called "future objects" that enable replacing a future instantiation of an object with a previously created fake object:

 // Create fake (stub/mock whateever) objects
 var fakeSqlConnection = Isolate.Fake.Instance<SqlConnection>();
 var fakeCommand = Isolate.Fake.Instance<SqlCommand>();
 Isolate.WhenCalled(() => fakeSqlConnection.CreateCommand()).WillReturn(fakeCommand);

 var fakeReader = Isolate.Fake.Instance<SqlDataReader>();
 Isolate.WhenCalled(() => fakeCommand.ExecuteReader()).WillReturn(fakeReader);

 // Next time SQLConnection is instantiated replace with our fake
 Isolate.Swap.NextInstance<SqlConnection>().With(fakeSqlConnection);

Problem

I'm trying to define a way to simulate an case on accessing into a database without accessing... That's probably sounds quite crazy, but it's not. Here is an example about a method i would like to test: ``` public IDevice GetDeviceFromRepository(string name) { IDevice device = null; IDbConnection connection = new SqlConnection(ConnectionString); connection.Open(); try { IDbCommand command = connection.CreateCommand(); command.CommandText = string.Format("SELECT DEVICE_ID,DEVICE_NAME FROM DEVICE WHERE DEVICE_NAME='{0}'", name); IDataReader dataReader = command.ExecuteReader(); if(dataReader.NextResult()) { device = new Device(dataReader.GetInt32(0),dataReader.GetString(1)); } } finally { connection.Close(); } return device; } ``` I'm pretending to mock IDataReader so i can control what's being read. Something like that (using Moq framework): ``` [TestMethod()] public void GetDeviceFromRepositoryTest() { Mock<IDataReader> dataReaderMock = new Mock<IDataReader>(); dataReaderMock.Setup(x => x.NextResult()).Returns(true); dataReaderMock.Setup(x => x.GetInt32(0)).Returns(000); dataReaderMock.Setup(x => x.GetString(1)).Returns("myName"); Mock<IDbCommand> commandMock = new Mock<IDbCommand>(); commandMock.Setup(x => x.ExecuteReader()).Returns(dataReaderMock.Object); Mock<RemoveDeviceManager> removeMock = new Mock<RemoveDeviceManager>(); removeMock.Setup() RemoveDeviceManager target =new RemoveDeviceManager(new Device(000, "myName")); string name = string.Empty; IDevice expected = new Device(000, "myName"); // TODO: Initialize to an appropriate value IDevice actual; actual = target.GetDeviceFromRepository(name); Assert.AreEqual(expected.SerialNumber, actual.SerialNumber); Assert.AreEqual(expected.Name, actual.Name); } ``` My question is whether i can force method GetDeviceFromRepository to replace IDataReader by mocked one.

Original source

Related problems