Is Mocking able to replace functionality wrapped inside a method? - c#

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.

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);

I would think the problem here is your direct dependency ultimately to SqlConnection. If you would use some variant of dependency injection such that your code gets access to the IDbCommand without knowing how it gets constructed, you would be able to inject your mock without much of a hassle.
I understand this doesn't quite answer your question, but in the long run doing stuff as described will give you far better testability.

I agree with Frank's answer that moving toward Dependency Injection is the better long-term solution, but there are some intermediate steps you can take to move you in that direction without biting the whole thing off.
One thing is to move the construction of the IDbConnection class into a protected virtual method inside your class:
protected virtual IDbConnection CreateConnection()
{
return new SqlConnection(ConnectionString);
}
Then, you can create a testing version of your class like so:
public class TestingRemoteDeviceManager : RemoteDeviceManager
{
public override IDbConnection CreateConnection()
{
IDbConnection conn = new Mock<IDbConnection>();
//mock out the rest of the interface, as well as the IDbCommand and
//IDataReader interfaces
return conn;
}
}
That returns a Mock or fake IDbConnection instead of the concrete SqlConnection. That fake can then return a fake IDbCommand object, which can then return a fake IDataReader object.

The mantra is test until fear is transformed in boredom. I think you've crossed that line here. If you would take control of the data reader, then the only code you're testing is this:
device = new Device(dataReader.GetInt32(0),dataReader.GetString(1));
There is almost nothing to test here, which is good: the data layer should be simple and stupid. So don't try to unit test your data layer. If you feel you must test it, then integration-test it against a real database.
Of course, hiding your data layer behind a IDeviceRepository interface so that you can easily mock it in order to test other code is still a good idea.

Related

Nsubsitute mocking AS/IS .net

I am having hard time mocking IDbConnection. I have a method that returns IDbConnection but than I have a check to verify if this connection is NpgsqlConnection like this:
if (conn as NpgsqlConnection == null)
{
throw new System.Exception("error");
}
and while method returns mock object, casting(as) returns null and creates an exception. How can I use NSubsiute so it will treat it as NpgsqlConnection object?
And second question that is following up, if this one could be resolved is that I am using BeginBinaryImport from NpgsqlConnection which does not have an interface and I cannot mock it, how can I fake it, so it won't throw an error when used like this using var importer = conn.BeginBinaryImport("COPY..... ?
It depends on what you want to test actually. If you want to test the functionality of NpgsqlConnection also, you can create a NpgsqlConnection with a test connection string.
public void DoSomething()
{
// returns NpgsqlConnection with test connection string
// If you substituted for a class rather than an interface, check that the call to your substitute was on a virtual/abstract member.
IDbConnection conn = _connectionManager.GetConnection();
if (conn as NpgsqlConnection == null)
{
throw new System.Exception("error");
}
// functionality
using (var writer = (conn as NpgsqlConnection).BeginBinaryImport("COPY data (field_text, field_int4) FROM STDIN BINARY"))
{
// do some stuff
}
}
Here. You can make _connectionManager.GetConnection(); to return a test db connection which is a NpgsqlConnection. So you can test the code.
You can set it up like this:
var testConnection = new NpgsqlConnection("TESTCONNECTIONSTRING");
var conn = Substitute.For<ConnectionManager>();
conn.GetConnection().Returns(testConnection);
Otherwise, You need a dependency which abstracts functionality away from calling code. You don't need to worry too much about what a dependency is doing.
Your code can be something like this instead:
public void DoSomething()
{
IDbConnection conn = _connectionManager.GetConnection(); // returns NpgsqlConnection
_npgsqlConnectionHelper.ValidateConnection(conn);
_npgsqlConnectionHelper.DoFunctionality(conn);
}
Here, you can mock _npgsqlConnectionHelper

Disposing of a SqlConnection manually in XUnit tests

I am writing SQL Server integration tests using xUnit.
My tests look like this:
[Fact]
public void Test()
{
using (IDbConnection connection = new SqlConnection(_connectionString))
{
connection.Open();
connection.Query(#$"...");
//DO SOMETHING
}
}
Since I am planning to create multiple tests in the same class I was trying to avoid creating a new SqlConnection every time. I know that xUnit framework per se creates an instance of the class per each running test inside it.
This means I could make the creation of the SqlConnection in the constructor since anyway a new one will be created every time a new test run.
The problem is disposing it. Is it good practice or do you see any problem in disposing manually the SqlConnection at the end of each test?
Such as:
public class MyTestClass
{
private const string _connectionString = "...";
private readonly IDbConnection _connection;
public MyTestClass()
{
_connection = new SqlConnection(_connectionString));
}
[Fact]
public void Test()
{
_connection.Open();
_connection.Query(#$"...");
//DO SOMETHING
_connection.Dispose();
}
}
I was trying to avoid creating a new SqlConnection every time.
It's okay to create and dispose a new SqlConnection over and over. The connection instance is disposed, but the underlying connection is pooled. Under the hood it may actually use the same connection repeatedly without closing it, and that's okay.
See SQL Server Connection Pooling.
So if that's your concern, don't worry. What you are doing in the first example is completely harmless. And however your code is structured, if you're creating a new connection when you need it, using it, and disposing it, that's fine. You can do that all day long.
If what concerns you is the repetitive code, I find this helpful. I often have a class like this in my unit tests:
static class SqlExecution
{
public static void ExecuteSql(string sql)
{
using (var connection = new SqlConnection(GetConnectionString()))
{
using (var command = new SqlCommand(sql, connection))
{
connection.Open();
command.ExecuteNonQuery();
}
}
}
public static T ExecuteScalar<T>(string sql)
{
using (var connection = new SqlConnection(GetConnectionString()))
{
using (var command = new SqlCommand(sql, connection))
{
connection.Open();
return (T)command.ExecuteScalar();
}
}
}
public static string GetConnectionString()
{
// This may vary
}
}
How you obtain the connection string may vary, which is why I left that method empty. It might be a configuration file, or it could be hard-coded.
This covers the common scenarios of executing something and retrieving a value, and allows me to keep all the repetitive database code out of my tests. Within the test is just one line:
SqlExecution.ExecuteSql("UPDATE WHATEVER");
You can also use dependency injection with xUnit, so you could write something as an instance class and inject it. But I doubt that it's worth the effort.
If I find myself writing more and more repetitive code then I might add test-specific methods. For example the test class might have a method that executes a certain stored procedure or formats arguments into a query and executes it.
You can also do dependency injection with xUnit so that dependencies are injected into the class like with any other class. There are lots of answers about this. You may find it useful. Maybe it's the reason why you're using xUnit. But something simpler might get the job done.
Someone is bound to say that unit tests shouldn't talk to the database. And they're mostly right. But it doesn't matter. Sometimes we have to do it anyway. Maybe the code we need
to unit test is a stored procedure, and executing it from a unit test and verifying the
results is the simplest way to do that.
Someone else might say that we shouldn't have logic in the database that needs testing, and I agree with them too. But we don't always have that choice. If I have to put logic in SQL I still want to test it, and writing a unit test is usually the easiest way. (We can call it an "integration test" if it makes anyone happy.)
There's a couple different things at play here. First, SqlConnection uses connection pooling so it should be fine to create/dispose the connections within a single test.
Having said that disposing of the connections on a per test class basis would also be doable. XUnit will dispose of test classes that are IDisposable. So either would work. I'd suggest it's cleaner to create/dispose them within the test.
public class MyTestClass : IDisposable
{
const string ConnectionStr = "";
SqlConnection conn;
public MyTestClass()
{
this.conn = new SqlConnection(ConnectionStr);
}
public void Dispose()
{
this.conn?.Dispose();
this.conn = null;
}
public void Test()
{
using (var conn = new SqlConnection(ConnectionStr))
{
}
}
}

Hot to write Unit Test case for SqlDataReader using Moq

I have following methods and want to write the Unit test case for mapping result through DataReader.
public interface IIMGAdvancedSearchDBProvider
{
clsGPAdvancedSearchResult GetSearchResult(clsIMGAdvancedImageSearchCriteria searchCriteria);
}
public class clsIMGAdvancedSearchSQLDBProvider : IIMGAdvancedSearchDBProvider
{
public clsGLGJSearchResultItem GetSearchResult(clsIMGAdvancedImageSearchCriteria searchCriteria)
{
using (var sqlConnection = DfxDbConnection)
{
using (var sqlCommand = sqlConnection.CreateCommand())
{
sqlCommand.Parameters.Add("#userKey", SqlDbType.UniqueIdentifier).Value = State.WebUserKey;
sqlCommand.Parameters.Add("#SiteCode", SqlDbType.VarChar).Value = State.SiteCode;
sqlCommand.Parameters.Add("#MaxRows", SqlDbType.Int).Value = searchCriteria.MaxRows;
//Add required client, client group filter paramters
AddClientAndClientGroupFilterParameters(searchCriteria, sqlCommand);
sqlCommand.CommandType = CommandType.Text;
sqlCommand.CommandText = GetCompleteSQLStatement(searchCriteria);
var reader = sqlCommand.ExecuteReader();
return alTransaction(reader);
reader.Close();
}
}
return null;
}
private clsGLGJSearchResultItem GetJournalTransaction(SqlDataReader reader)
{
return new clsGLGJSearchResultItem
{
ClientKey = DfxUtilities.GetGuidValueFromReader(reader, "ClientKey") ?? Guid.Empty,
JournalId = DfxUtilities.GetLongValueFromReader(reader, "JournalID") ?? 0,
AccountingDate = (DateTime)reader["Date"],
JournalSource =
(enumJournalSources)
Enum.Parse(typeof(enumJournalSources), reader["Source"].ToString()),
Description = DfxUtilities.GetStringValueFromReader(reader, "Description"),
DebitAmount = DfxUtilities.GetDecimalValueFromReader(reader, "DebitAmount") ?? 0,
CreditAmount = DfxUtilities.GetDecimalValueFromReader(reader, "CreditAmount") ?? 0,
ClientCode = DfxUtilities.GetStringValueFromReader(reader, "ClientCode"),
ClientName = DfxUtilities.GetStringValueFromReader(reader, "ClientName"),
Images = GetImageItems(reader)
};
}
}
Can anybody help me to resolve this?
I think you'll be better off treating your data abstraction layer (DAL) interfaces and classes (like IIMGAdvancedSearchDBProvider and clsIMGAdvancedSearchSQLDBProvider) as components that you integration test rather than unit test.
In other words, combine testing of the database schema, triggers, seed test data + your DAL implementation class (including the call to ExecuteReader). DALs should be thin and exclude business logic as yours does. You'd typically setup/teardown test data in the database for these integration tests. You might also want to create a common base class for these DAL integration test classes to setup your test database connection and perhaps some SQL logging. Might also maintain a separate test database with edge test case data or otherwise inject this data in setup/teardowns. No Mocking here.
Then you can unit test the business layer classes above it by mocking the values returned by your DAL interface IIMGAdvancedSearchDBProvider in the components/classes that use the DAL interface. I often try to complete the DAL testing first and capture some snapshots of "real production data" cases that I then return from my Mock DAL objects to the business layer unit tests. This avoids creating Mocks that miss the real data edge cases that are in the production data.
If you're using NUnit, consider using their TestCase, Pairwise and Combinatorial attributes to generated test cases (rather than mocking them) for your business layer objects. You might also find my ShouldBe wrapper library handy.
BTW ... Your cls class prefix naming convention is non-standard.

What is a good approach to get rid of dependency on a StreamReader/FileStream for Unit Tests?

Here's the scenario:
I have a method that reads in a file via a FileStream and a StreamReader in .NET. I would like to unit test this method and somehow remove the dependency on the StreamReader object.
Ideally I would like to be able to supply my own string of test data instead of using a real file. Right now the method makes use of the StreamReader.ReadLine method throughout. What is an approach to modifying the design I have now in order to make this test possible?
Depend on Stream and TextReader instead. Then your unit tests can use MemoryStream and StringReader. (Or load resources from inside your test assembly if necessary.)
Note how ReadLine is originally declared by TextReader, not StreamReader.
The simplest solution would be to have the method accept a Stream as a parameter instead of opening its own FileStream. Your actual code could pass in the FileStream as usual, while your test method could either use a different FileStream for test data, or a MemoryStream filled up with what you wanted to test (that wouldn't require a file).
Off the top of my head, I'd say this is a great opportunity to investigate the merits of Dependency Injection.
You might want to consider redesigning your method so that it takes a delegate that returns the file's contents. One delegate (the production one) might use the classes in System.IO, while the second one (for unit testing), returns the contents directly as a string.
I think the idea is to dependency inject the TextReader and mock it for unit testing. I think you can only mock the TextReader because it is an abstract class.
public class FileParser
{
private readonly TextReader _textReader;
public FileParser(TextReader reader)
{
_textReader = reader;
}
public List<TradeInfo> ProcessFile()
{
var rows = _textReader.ReadLine().Split(new[] { ',' }).Take(4);
return FeedMapper(rows.ToList());
}
private List<TradeInfo> FeedMapper(List<String> rows)
{
var row = rows.Take(4).ToList();
var trades = new List<TradeInfo>();
trades.Add(new TradeInfo { TradeId = row[0], FutureValue = Convert.ToInt32(row[1]), NotionalValue = Convert.ToInt32(row[3]), PresentValue = Convert.ToInt32(row[2]) });
return trades;
}
}
and then Mock using Rhino Mock
public class UnitTest1
{
[Test]
public void Test_Extract_First_Row_Mocked()
{
//Arrange
List<TradeInfo> listExpected = new List<TradeInfo>();
var tradeInfo = new TradeInfo() { TradeId = "0453", FutureValue = 2000000, PresentValue = 3000000, NotionalValue = 400000 };
listExpected.Add(tradeInfo);
var textReader = MockRepository.GenerateMock<TextReader>();
textReader.Expect(tr => tr.ReadLine()).Return("0453, 2000000, 3000000, 400000");
var fileParser = new FileParser(textReader);
var list = fileParser.ProcessFile();
listExpected.ShouldAllBeEquivalentTo(list);
}
}
BUT the question lies in the fact whether it is a good practice to pass such an object from the client code rather I feel it should be managed with using within the class responsible for processing. I agree with the idea of using a sep delegate for the actual code and one for the unit testing but again that is a bit of extra code in production. I may be a bit lost with the idea of dependency injection and mocking to even file IO open/read which actually is not a candidate for unit testing but the file processing logic is which can be tested by just passing the string content of the file (AAA23^YKL890^300000^TTRFGYUBARC).
Any ideas please! Thanks

Enterprise library manage connections

I am building an application with c# and I decided to use the Enterprise Library for the DAL (SQL Server).
I don't remember where, but I had read an article about EntLib which said that the connections are closed automatically.
Is it true?
If not, what is the best approach of managing the connections in the middle layer?
Open and close in each method?
The above is a sample method of how I am using the EntLib
public DataSet ReturnSomething
{
var sqlStr = "select something";
DbCommand cmd = db.GetSqlStringCommand(sqlStr);
db.AddInParameter(cmd, "#param1", SqlDbType.BigInt, hotelID);
db.AddInParameter(cmd, "#param2", SqlDbType.NVarChar, date);
return db.ExecuteDataSet(cmd);
}
Thanks in advance.
the ExecuteDataSet method returns a DataSet object that contains all the data. This gives you your own local copy. The call to ExecuteDataSet opens a connection, populates a DataSet, and closes the connection before returning the result
for more info:
http://msdn.microsoft.com/en-us/library/ff648933.aspx
I think you should have something like a static class used as a Façade which would provide the correct connection for your library subsystems.
public static class SystemFacade {
// Used as a subsystem to which the connections are provided.
private static readonly SystemFactory _systemFactory = new SystemFactory();
public static IList<Customer> GetCustomers() {
using (var connection = OpenConnection(nameOfEntLibNamedConnection))
return _systemFactory.GetCustomers(connection);
}
public static DbConnection OpenConnection(string connectionName) {
var connection =
// Read EntLib config and create a new connection here, and assure
// it is opened before you return it.
if (connection.State == ConnectionState.Closed)
connection.Open();
return connection;
}
}
internal class SystemFactory {
internal IList<Customer> GetCustomers(DbConnection connection) {
// Place code to get customers here.
}
}
And using this code:
public class MyPageClass {
private void DisplayCustomers() {
GridView.DataSource = SystemFacade.GetCustomers();
}
}
In this code sample, you have a static class that provides the functionalities and features of a class library. The Façade class is used to provide the user with all possible action, but you don't want to get a headache with what connection to use, etc. All you want is the list of customers out of the underlying datastore. Then, a call to GetCustomers will do it.
The Façade is an "intelligent" class that knows where to get the information from, so creates the connection accordingly and order the customers from the subsystem factory. The factory does what it is asked for, take the available connection and retrieve the customers without asking any further questions.
Does this help?
Yes, EntLib closes connections for you (actually it releases them back into the connection pool). That is the main reason why we originally started to use EntLib.
However, for all new development we have now gone on to use Entity Framework, we find that much more productive.

Categories