How can I mock a static extension method in dbContext - c#

I'm trying to create a test to mock the execution the stored procedure. I have a static class called LoadStoredProcedure this create a dbCommand
public static DbCommand LoadStoredProc(this DbContext context, string storedProcName, bool prependDefaultSchema = true, short commandTimeout = 30)
{
var cmd = context.Database?.GetDbConnection()?.CreateCommand();
cmd.CommandTimeout = commandTimeout;
if (prependDefaultSchema)
{
var schemaName = context.Model.GetDefaultSchema();
if (schemaName != null)
{
storedProcName = $"{schemaName}.{storedProcName}";
}
}
cmd.CommandText = storedProcName;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
return cmd;
}
but this is an static method, and here i have a mock of the dbContext
public static async Task<BTContext> getBtContextForStoreProcedure()
{
try
{
var options = new DbContextOptionsBuilder<BTContext>()
.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
.Options;
Mock<BTContext> context = new Mock<BTContext>(options);
List<responseStored> list = new()
{
new responseStored() {
p_return_value=new MySqlParameter { ParameterName = "#p_servicable", Value = 10 }
}
};
var optionss = new DbContextOptionsBuilder<BTContext>().UseInMemoryDatabase(Guid.NewGuid().ToString()).Options;
var dbContextToMock = new BTContext(options);
Mock<DbContext> mocked = new();
var mockedDbContext = new MockedDbContextBuilder<BTContext>().UseDbContext(dbContextToMock).UseConstructorWithParameters(optionss).MockedDbContext;
/*var another = mockedDbContext.Database.GetDbConnection();
context.Setup(s =>s.Database.GetDbConnection()).Returns(another);*/
/*mocked.Setup(s => s.LoadStoredProc(It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<short>())).Returns;*/
mocked.Setup(s => s.LoadStoredProc(It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<short>()).
WithSqlParam(It.IsAny<List<MySqlParameter>>()).ExecuteStoredProcAsync<responseStored>()).ReturnsAsync(list);
return context.Object;
}
catch(Exception ex)
{
throw new Exception(ex.Message);
}
}
but return this error
unsupported expression extension methods may not be used in setup / verification expressions

This is not possible. You cannot mock a static method, and so you cannot mock an extension method either.
One way to do this is to change LoadStoredProc into a virtual method of a factory class (or an interface). Or you live with the fact and create Setup's for the implementation of the LoadStoredProc method. That would mean you would create an expectation for the Database property with something like mocked.Setup(x => x.Database).Returns(something).

Related

Unit testing data layer's stored functions/procedures using OrmLite without an open connection

I am trying to unit test our DB layer's stored procedures/functions using OrmLite's ScalarAsync(), for example, with the PostgreSQL dialect. (I tried using SqlLite in-memory but it doesn't do stored procedures or functions.)
I found some hints in the unit-tests for OrmLite on GitHub as well as an article which points to them.
Here's what I have:
[Fact]
public async Task TestMyMethod_CallsMyStoredProcedure()
{
// Arrange
Mock<IDashboardDbConnectionFactory> mockConnFac = new();
MockDialectProvider prov = new();
prov.ExecFilter = new MockStoredProcExecFilter();
OrmLiteConnectionFactory dbFactory =
new(
"User ID=asdf;Password=asdf;Host=localhost;Port=5432;Database=asdf;Pooling=true;Connection Lifetime=0;",
prov, false);
OrmLiteConfig.ExecFilter = new MockStoredProcExecFilter();
mockConnFac.Setup(m => m.OpenAsync(It.IsAny<ISecurityContext>()))
.Returns(async () =>
{
OrmLiteConnection asdf = new(dbFactory);
OrmLiteConfig.ExecFilter = new MockStoredProcExecFilter();
await asdf.OpenAsync();
return asdf;
});
mockConnFac.Setup(m => m.Open(It.IsAny<ISecurityContext>()))
.Returns(() =>
{
OrmLiteConnection asdf = new(dbFactory);
OrmLiteConfig.ExecFilter = new MockStoredProcExecFilter();
asdf.Open();
return asdf;
});
// Act
MyDataLayerCLass target = new(mockConnFac.Object, new NullLoggerFactory());
bool test1 =
await target.ExecMyStoredProcAsync(new Mock<ISecurityContext>().Object, Guid.NewGuid());
// Assert
Assert.True(test1);
}
private class MockDialectProvider : PostgreSqlDialectProvider
{
public MockDialectProvider()
{
base.ExecFilter = new MockStoredProcExecFilter();
}
public new IOrmLiteExecFilter ExecFilter { get; set; } = new MockStoredProcExecFilter();
}
private class MockStoredProcExecFilter : OrmLiteExecFilter
{
public override T Exec<T>(IDbConnection dbConn, Func<IDbCommand, T> filter)
{
try
{
T val = base.Exec(dbConn, filter);
if (dbConn.GetLastSql() == "select central_data.my_stored_function(#UserId, #ParentId)")
return (T)(object)true;
return val;
}
catch (Exception)
{
if (dbConn.GetLastSql() == "select central_data.my_stored_function(#UserId, #ParentId)")
return (T)(object)true;
throw;
}
}
public override async Task<T> Exec<T>(IDbConnection dbConn, Func<IDbCommand, Task<T>> filter)
{
try
{
// This is where the breakpoint hits. Returns false b/c the ids
// don't match actual records in the DB.
T val = await base.Exec(dbConn, filter);
if (dbConn.GetLastSql() == "select central_data.my_stored_function(#UserId, #ParentId)")
return (T)(object)true;
return val;
}
catch (Exception)
{
string sql = dbConn.GetLastSql();
if (sql == "select central_data.my_stored_function(#UserId, #ParentId)")
{
return (T)(object)true;
}
throw;
}
}
}
The problem is that it requires a valid connection to a valid database. So it's really an integration test when what I want is a unit test. Is there a way to run the dialect provider without an open connection?

How to mock method which is called multiple times c#

I have a common method which is being called multiple times(around 30-35 references in the project). This method is basically fetching data from DB into data table.
Following is the testable code:
public class MyApp
{
private readonly IDataProvider _dbProvider;
public MyApp(IDataProvider dbProvider)
{
_dbProvider = dbProvider;
}
public void Process()
{
string query = "something";
Helper h = new Helper(_dbProvider);
// This method will be called in the Process method several times
var data = h.GetData(query);
}
}
public interface IDataProvider
{
IDbConnection CreateConnection(string connectionString);
DataTable FillDatatableFromAdapter(IDbCommand command);
}
public class DataProvider : IDataProvider
{
public IDbConnection CreateConnection(string connectionString)
{
return new SqlConnection(connectionString);
}
public DataTable FillDatatableFromAdapter(IDbCommand command)
{
DataSet dataSet = new DataSet();
SqlCommand sqlCommand = command as SqlCommand;
using (SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlCommand))
{
sqlDataAdapter.Fill(dataSet);
}
if (dataSet.Tables.Count == 0)
return null;
return dataSet.Tables[0];
}
}
public class Helper
{
private readonly IDataProvider _dbProvider;
public Helper(IDataProvider dbProvider)
{
_dbProvider = dbProvider;
}
public DataTable GetData(string query)
{
DataTable table = new DataTable();
using (IDbConnection connection =
_databaseProvider.CreateConnection(_connectionString))
{
connection.Open();
using (IDbCommand command = connection.CreateCommand())
{
command.CommandText = query;
command.Connection = connection;
table = _dbProvider.FillDatatableFromAdapter(command);
}
}
return table;
}
}
I have mocked DB classes to not hit DB from unit tests.
Following is the test case code:
[TestMethod]
public void TestMyApp()
{
Mock<IDbCommand> mockDbCommand = new Mock<IDbCommand>();
Mock<IDbConnection> mockDbConnection = new Mock<IDbConnection>();
Mock<IDataProvider> mockDatabaseProvider = new Mock<IDataProvider();
mockDbConnection.Setup(m => m.CreateCommand()).Returns(mockDbCommand.Object);
mockDatabaseProvider.Setup(m => m.CreateConnection(It.IsAny<string>())).Returns(mockDbConnection.Object);
DataTable table = new DataTable();
mockDatabaseProvider.SetupSequence(mock => mock.FillDatatableFromAdapter(It.IsAny<IDbCommand>()))
.Returns(dataTable);
MyApp app = new MyApp(mockDatabaseProvider.Object);
app.Process();
// And then after that I am testing some data.
}
I will be calling GetData() method several times and therefore FillDatatableFromAdapter will also be called several times. As in the above test case I have mocked FillDatatableFromAdapter method and I am returning some fake data table for further testing.
I am aware of SetupSequence method in Moq which I can use to return multiple data tables from the mocked method everytime that method is called.
I want a suggestion is that approach correct because then I will have to create that many number of Data tables which will be return from the mocked method using SetupSequence? Or is there some other better approach?
Any help??
You need to define what you want to test.
A small refactoring will help you better test your code
public class MyApp
{
private readonly IDataProvider _dbProvider;
private readonly IHelper _h;
public MyApp(IDataProvider dbProvider)
{
_dbProvider = dbProvider;
_h = new Helper(_dbProvider);
}
public void Process()
{
string query = "something";
// This method will be called in the Process method several times
var data = _h.GetData(query);
}
}
public interface IDataProvider
{
IDbConnection CreateConnection(string connectionString);
DataTable FillDatatableFromAdapter(IDbCommand command);
}
public class DataProvider : IDataProvider
{
public IDbConnection CreateConnection(string connectionString)
{
return new SqlConnection(connectionString);
}
public DataTable FillDatatableFromAdapter(IDbCommand command)
{
DataSet dataSet = new DataSet();
SqlCommand sqlCommand = command as SqlCommand;
using (SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlCommand))
{
sqlDataAdapter.Fill(dataSet);
}
if (dataSet.Tables.Count == 0)
return null;
return dataSet.Tables[0];
}
}
public interface IHelper
{
public DataTable GetData(string query);
}
public class Helper
{
private readonly IDataProvider _dbProvider;
public Helper(IDataProvider dbProvider)
{
_dbProvider = dbProvider;
}
public DataTable GetData(string query)
{
DataTable table = new DataTable();
using (IDbConnection connection =
_databaseProvider.CreateConnection(_connectionString))
{
connection.Open();
using (IDbCommand command = connection.CreateCommand())
{
command.CommandText = query;
command.Connection = connection;
table = _dbProvider.FillDatatableFromAdapter(command);
}
}
return table;
}
}
Now you can have 4 isolated tests
[TestMethod]
public void TestProccessFunctionCallHelperGetData()
{
Mock<IHelper> mockHelper = new Mock<IHelper>();
Mock<IDataProvider> mockDatabaseProvider = new Mock<IDataProvider();
mockHelper.Setup(m => m.getData(It.IsAny<string>())).Returns(new DataTable());
MyApp app = new MyApp(mockDatabaseProvider.Object, mockHelper.Setup);
app.Process();
Assert.AreEquals(mockHelper.numTimesCalled, 1);
}
[TestMethod]
public void TestHelperGetData()
{
var query = ""; //TODO: write dummy query
var dataTableToReturn = new DataTable(); //TODO: add some data
Mock<IDataProvider> mockDatabaseProvider = new Mock<IDataProvider();
mockDatabaseProvider.Setup(m => m.CreateConnection(It.IsAny<string>())).Returns(new SqlConnection("dummy connection string"));
mockDatabaseProvider.Setup(m => m.FillDatatableFromAdapter(It.IsAny<IDbCommand>())).Returns(dataTableToReturn );
IHelper h = new Helper(mockDatabaseProvider.Object);
var actualDataTable = h.getData(query);
Assert.AreEqual(dataTableToReturn, actualDataTable );
}
[TestMethod]
public void TestDataProviderFillDataTableFromAdapter()
{
//This test seems to me more like integration test because you need to mock a db or use a real db
}
[TestMethod]
public void TestYourData()
{
// Create a dataTable with data so you can continue with your testing
}

Using interface and abstract class in repository pattern in ASP.NET Core

We are currently using dapper ORM to access data by calling store procedures. The current code is having a class BusinessFunctions which inherits another class DataFunctions which are having helper methods to execute the stored procedures.
I am not happy with this code. It's just too rigid and not future proof. And above all it's not coded to an interface rather coded to an implementation. I propose an interface IRepository with an abstract class Repository which implements all helper generic methods. Then I create BusinessRepository that implements the abstract Repository class and call the generic helpers method. Again, my colleague is telling me to remove the IRepository interface and just use the Repository abstract class.
public class BusinessFunctions : DataFunctions
{
public BusinessFunctions(ConnectionManager conMgr, LogWriter logWriter, AppUser appUser) : base(conMgr, logWriter, appUser)
{
}
public async Task<Business> FindAsync(int businessId)
{
throw new NotImplementedException();
}
public async Task<Business> FindAsync(string businessGuid)
{
var lst = await StoredProcQueryAsync<Business>("spBusinessGetSetupGUID", new { BusinessGuid = businessGuid });
if (lst.Count() == 0)
throw new NotFoundInDatabaseException("Business", businessGuid);
else
return lst.Single();
}
public async Task<bool> IsHostedTokenizeCardAllowedAsync(string businessGuid)
{
var b = await FindAsync(businessGuid);
if (b.HostedPaymentEnabled)
return true;
else
return false;
}
}
public class DataFunctions : IDisposable
{
private ConnectionManager _conMgr;
private LogWriter _logWriter;
private AppUser _appUser;
public ConnectionManager ConnMgr
{
get { return _conMgr; }
}
protected LogWriter Logger
{
get { return _logWriter; }
}
protected AppUser User
{
get { return _appUser; }
}
public DataFunctions(ConnectionManager conMgr, LogWriter logWriter, AppUser appUser)
{
_conMgr = conMgr;
_logWriter = logWriter;
_appUser = appUser;
}
public void Dispose()
{
}
public async Task StoredProcExecuteNonQueryAsync(string storedProc,
List<StoredProcParameter> storedProcParameters = null,
SqlCommandTimeout commandTimeout = SqlCommandTimeout.Default,
SqlAccessType accessType = SqlAccessType.ReadWrite
)
{
using (SqlConnection conn = new SqlConnection(ConnMgr.SqlConnectionString))
{
await conn.OpenAsync();
await StoredProcExecuteNonQueryAsync(conn,
storedProc,
storedProcParameters: storedProcParameters,
commandTimeout: commandTimeout,
accessType: accessType);
}
}
public async Task StoredProcExecuteNonQueryAsync(SqlConnection conn,
string storedProc,
List<StoredProcParameter> storedProcParameters = null,
SqlCommandTimeout commandTimeout = SqlCommandTimeout.Default,
SqlAccessType accessType = SqlAccessType.ReadWrite,
SqlTransaction trans = null
)
{
using (SqlCommand cmd = new SqlCommand(storedProc, conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = (int)commandTimeout;
if (trans != null) cmd.Transaction = trans;
if (storedProcParameters != null)
{
foreach(var p in storedProcParameters)
{
cmd.Parameters.Add(p.ToSqlParameter());
}
}
await cmd.ExecuteNonQueryAsync();
}
}
public async Task<IEnumerable<T>> StoredProcQueryAsync<T>(string storedProc,
object storedProcParameters = null,
SqlCommandTimeout commandTimeout = SqlCommandTimeout.Default,
SqlAccessType accessType = SqlAccessType.ReadWrite)
{
using (SqlConnection conn = new SqlConnection(ConnMgr.SqlConnectionString))
{
conn.Open();
return await StoredProcQueryAsync<T>(conn,
storedProc,
storedProcParameters,
commandTimeout);
}
}
public async Task<IEnumerable<T>> StoredProcQueryAsync<T>(SqlConnection conn,
string storedProc,
object storedProcParameters = null,
SqlCommandTimeout commandTimeout = SqlCommandTimeout.Default)
{
return await conn.QueryAsync<T>(storedProc,
commandType: CommandType.StoredProcedure,
commandTimeout: (int)commandTimeout,
param: storedProcParameters);
}
}
I think the reason you're unhappy with the code is that it seems to be intermingling service functionality into the repository layer. The repository layer should simply call the stored procedure.
public async Task<bool> IsHostedTokenizeCardAllowedAsync(string businessGuid)
{
var b = await FindAsync(businessGuid);
if (b.HostedPaymentEnabled)
return true;
else
return false;
}
This for example is a good candidate to be in the service layer.
Your repo layer should really just have your ConnectionManager or a Connection factory injected via IoC.
The trick we use is to put an attribute on data model fields that we know are going to be stored procedure parameters (usually most or all). Then we have an extension method that reflects over the attributes and pulls the fields, values, and types creating a dapper DynamicParameters object. Most of our repository calls look like this:
public async Task<User> AddUserAsync(UserAdd user)
{
using (var connection = _connectionFactory.Create()
{
var result = connection.ExecuteAsync("dbo.AddUser", user.GetParameters(), commandType: CommandType.StoredProcedure";
return result;
}
}
It's relatively quick and easy to use. Gets are very easy to test. Inserts/Deletes/Updates not so much. You get into needing to mock the SqlConnection which can be problematic.
In addition, if you get into more complex areas that are subject to change, you can use the strategy pattern to move methods into their own classes. Below would be an example of splitting your add method into its own class:
public class MyRepository
{
private readonly IAddMethod<UserAdd> _addMethod;
private readonly IConnectionFactory _connectionFactory;
public MyRepository(IAddMethod<UserAdd> userAddMethod,
IConnectionFactory connectionFactory)
{
//..guard clauses, assignments, etc.
}
public async Task<int> AddAsync(UserAdd user)
{
return _addMethod.AddAsync(user);
}
}
You can even decorate these strategy methods in IoC to hide/augment them as needed. (in structuremap it's .DecorateAllWith()
In short, move any logic to the service layer, consider a generic extension method for creating your DynamicParameters list, and inject the connection factory via IoC. I think you'll find the separation of concerns will simplify things significantly.

Generic method where T implements Interface<T>

I'm trying to create a generic data retrieval process. What I have currently works, but there is a part of it that doesn't seem right and I'm hoping there is a better way to accomplish it.
So the idea is that I have classes for each table in the database, here is an example of a class:
public class CMCGRGRGROUP : IFacetsObject<CMCGRGRGROUP>
{
public int GRGR_CK { get; set; }
public string GRGR_NAME { get; set; }
public string GRGR_ADDR1 { get; set; }
public IEnumerable<CMCGRGRGROUP> ToObject(DataTable table)
{
return table.AsEnumerable().Select(row =>
{
return new CMCGRGRGROUP
{
GRGR_CK = Convert.ToInt32(row["GRGR_CK"]),
GRGR_NAME = row["GRGR_NAME"].ToString(),
GRGR_ADDR1 = row["GRGR_ADDR1"].ToString()
};
});
}
}
You'll notice that the class implements an interface of its own type. The interface simply defines a method called ToObject, which is used to convert a datatable to a class of that particular type:
public interface IFacetsObject<T>
{
IEnumerable<T> ToObject(DataTable obj);
}
Now, here is the method that I am using to execute a query:
public IEnumerable<T> ExecuteQuery<T>(string sql, IFacetsObject<T> obj) where T : new()
{
using (var conn = new AseConnection(_conn))
{
conn.Open();
var cmd = new AseCommand(sql, conn);
var dt = new DataTable();
var da = new AseDataAdapter(sql, conn);
da.Fill(dt);
return obj.ToObject(dt); //this is the interface method
}
}
So the main question is:
How can the generic method know that T should implement IFacetsObject<T>? That way I don't have to pass IFacetsObject<T> as a parameter. Ideally, I could change the return line to be something like this:
return T.ToObject(dt);
And call it like this:
var result = ExecuteQuery<CMCGRGRGROUP>(sql).Take(5);
Instead of like this:
var result = ExecuteQuery<CMCGRGRGROUP>(sql, new CMCGRGRGROUP()).Take(5);
I'll admit that I'm not terribly familiar with generics yet so there may be something within the implementation that isn't right.
You can add a constraint on your ExecuteQuery method. You already have one: requiring that T be newable. You'd declare it like:
public IEnumerable<T> ExecuteQuery<T>(string sql, IFacetsObject<T> obj)
where T : IFacetsObject<T>, new()
{
using (var conn = new AseConnection(_conn))
{
conn.Open();
var cmd = new AseCommand(sql, conn);
var dt = new DataTable();
var da = new AseDataAdapter(sql, conn);
da.Fill(dt);
return obj.ToObject(dt); //this is the interface method
}
}
So it now knows T is an IFacetsObject<T>. You could now do:
public IEnumerable<T> ExecuteQuery<T>(string sql)
where T : IFacetsObject<T>, new()
{
using (var conn = new AseConnection(_conn))
{
conn.Open();
var cmd = new AseCommand(sql, conn);
var dt = new DataTable();
var da = new AseDataAdapter(sql, conn);
da.Fill(dt);
return new T().ToObject(dt); //this is the interface method
}
}
Which IMO is still pretty ugly.
EDIT Response:
Note that you cannot call T.ToObject - an interface cannot define a static method. The workaround is the use of new to create a new instance of T and call the instance method.
You need a generic constraint on your interface. Declare it like this:
public interface IFacetsObject<T> where T : IFacetsObject<T>
{
IEnumerable<T> ToObject(DataTable obj);
}
In order to get this to work, you also have to change your declaration like this:
public IEnumerable<T> ExecuteQuery<T>(string sql, IFacetsObject<T> obj)
where T : IFacetsObject<T>, new()

How to mock SqlParameterCollection using Moq

I am trying to mock database operations. I have problem in mocking SqlParameterCollection. I tried to create virtual method that will return DbParameterCollection but then i am loosing all the functionality that SqlParameterCollection gives like AddWithValue etc. Is there a way i can mock SqlParameterCollection? Is there any other approach to unit test DAL? I am using Moq.
Code goes like this:
in DAL:
protected virtual IDbConnection GetConnection(string connectionString)
{
return new SqlConnection(connectionString);
}
protected virtual IDbCommand GetCommand(IDbConnection cn)
{
return cn.CreateCommand();
}
protected virtual IDbTransaction GetTransaction(IDbConnection cn)
{
return cn.BeginTransaction(IsolationLevel.Serializable);
}
Public Bool InsertInDatabase(DataTable dt)
{
using (IDbConnection cn = GetConnection(cnstr))
{
cn.Open();
using (IDbTransaction tran = GetTransaction(cn))
{
IDbCommand cmd = GetCommand(cn);
cmd.Transaction = tran;
cmd.Connection = cn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sp_InsertInDatabase";
SqlParameterCollection cmdParams = cmd.Parameters as SqlParameterCollection;
cmdParams.AddWithValue("#param1", dt);
cmd.ExecuteNonQuery();
}
}
}
In Unit test project:
protected override IDbConnection GetConnection(string connectionString)
{
return Mock.Of<IDbConnection>();
}
protected override IDbCommand GetCommand(IDbConnection cn)
{
return Mock.Of<IDbCommand>();
}
protected override IDbTransaction GetTransaction(IDbConnection cn)
{
return Mock.Of<IDbTransaction>();
}
public void TestInsertInDatabase()
{
base.InsertInDatabase(new DataTable());
}
--Solution--
Created an extension method to add parameter with value. Thank you Marc Gravell for pointing me to that direction.
public static IDbDataParameter AddParameterWithValue(this IDbCommand cmd, string paramName, object paramValue)
{
var dbParam = cmd.CreateParameter();
if (dbParam != null)
{
dbParam.ParameterName = paramName;
dbParam.Value = paramValue;
}
return dbParam;
}
Personally, I approach this problem by writing an AddParameterWithValue extension method to DbCommand (or IDbCommand). It has to be on the command so that you have access to CreateParameter, and then call .Parameters.Add.
This allows easy usage against any ADO.NET stack, including abstractions like logging decorators.
#Asdfg HI I have basically mocked the parameter collection as below
string connectionString = "connectionstring";
var sqlConnection = new SqlConnection(connectionString);
var command = sqlConnection.CreateCommand();
//****************Setup Mock************************//
Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add(typeof(System.Data.SqlClient.SqlClientPermissionAttribute));
var mockDataReader1 = new Mock<IDataReader>();
command.Parameters.Add(new SqlParameter("#po_tint_Result", 1));
//setup read return value
Queue<bool> responseQueue = new Queue<bool>();
responseQueue.Enqueue(true);
responseQueue.Enqueue(false);
mockDataReader1.Setup(a => a.Read()).Returns(() => responseQueue.Dequeue());
var mockDb = new Mock<SqlDatabase>(connectionString);
mockDb.Setup(a => a.GetStoredProcCommand("SPNAME")).Returns(command);
mockDb.Setup(a => a.ExecuteNonQuery(command));
obj1.DbConn = mockDb.Object;
//*************************************************//
Hope this helps
Hi i found the solution.
I had to implement a Moq for the IDataParameterCollection interface and had to send it to the instance of IDbCommand.
With that my IDbCommand.Parameters object became different from null.
public static IDbConnection IDbConnectionMock(int valReturn)
{
var dataParameterCollection = new Mock<IDataParameterCollection>();
var command = new Mock<IDbCommand>();
command.Setup(x => x.Parameters).Returns(dataParameterCollection.Object);
command.Setup(x => x.ExecuteNonQuery()).Returns(valReturn);
var connection = DbConnectionMock_Success(command.Object);
return connection;
}

Categories

Resources