Por que Moles não está retornando DataSet “moled” ao zombar do SqlDataAdaptor?
-
15-11-2019 - |
Pergunta
Acabei de começar a usar Moles para simular alguns códigos legados complicados.Em essência, estou tentando fazer com que um SqlDataAdapter funcione com Moles.(Aliás, obtive sucesso ao usar moles com as classes SqlDataReader e SqlCommand.) Tentei criar um exemplo de teste de unidade "simples" abaixo, onde estou tentando fazer com que o SqlDataAdaptor "preencha" o DataSet fornecido.Então, ao usar Moles, estou zombando das várias chamadas na recuperação de dados do conjunto de dados.Acredito que configurei o DataSet corretamente para que a recuperação de dados retorne o objeto "moled" esperado e faça a coisa certa.
Quando executo o seguinte, posso ver que a expressão lambda FillDataSetString está sendo executada e "d" está sendo definido como ds "moled".Mas quando o método Fill retorna, o DataSet passado ("dset") ainda é um "DataSet" regular e não o "moled DataSet".Assim, o primeiro Assert não funciona corretamente e lança uma IndexOutOfRangeException ("Não é possível encontrar a tabela 0.").No primeiro Assert, espero que os seguintes métodos "moled" sejam chamados quando dset.Tables[0].Rows.Count for avaliado:
ds.TablesGet
tables.ItemGetInt32
table.RowsGet
rows.CountGet
Mas como dset não é o DataSet "moled", nenhuma dessas chamadas acontece.Qualquer ajuda para descobrir o que Moles está fazendo com o parâmetro de conjunto de dados do SqlDataAdapter seria muito apreciada.
Para que o procedimento abaixo funcione, você deve instalar "Moles", referenciar System.Data, System.Xml, criar uma referência "System.Data.moles".Estou usando 0.94.0.0 do framework Moles e executando-o no VS.NET 2010, com o "Target Framework" do projeto de teste definido como ".NET Framework 4.0".
using System.Data;
using System.Data.Moles;
using System.Data.Common.Moles;
using System.Data.SqlClient;
using System.Data.SqlClient.Moles;
using System.Xml.Serialization;
[TestClass]
public class UnitTest1
{
[TestMethod]
[HostType("Moles")]
public void IsolatedSqlDataAdaptorTest()
{
// Arrange
Dictionary<string, object> backing = new Dictionary<string, object>()
{
{"field", 5},
};
MSqlConnection.AllInstances.Open = (c) => { };
MSqlConnection.AllInstances.Close = (c) => { };
MSqlDataAdapter.ConstructorStringSqlConnection =
(@this, cmd, conn) =>
{
// Setup a moled DataSet with 1 Table and 1 Row
MDataRow row = new MDataRow()
{
// This is the method that ultimately gets called.
ItemGetString = (key) => { return backing[key]; },
};
MDataRowCollection rows = new MDataRowCollection();
rows.CountGet = () => { return 1; };
rows.ItemGetInt32 = (i) => { return row; };
MDataTable table = new MDataTable();
table.RowsGet = () => { return rows; };
MDataTableCollection tables = new MDataTableCollection();
tables.ItemGetInt32 = (i) => { return table; };
MDataSet ds = new MDataSet();
ds.TablesGet = () => { return tables; };
MSqlDataAdapter sdaMole = new MSqlDataAdapter(@this);
MDbDataAdapter ddaMole = new MDbDataAdapter(sdaMole)
{
FillDataSetString = (d, s) =>
{
d = ds;
return 1;
},
};
};
// Act
DataSet dset = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(
"select something from aTable",
new SqlConnection());
da.Fill(dset, "aTable");
// Assert
Assert.AreEqual(1, dset.Tables[0].Rows.Count, "Count");
Assert.AreEqual(5, dset.Tables[0].Rows[0]["field"], "field");
}
}
Solução
Dando uma nova olhada nesta questão depois de alguns meses, conforme solicitado por uma sugestão, de @StingyJack, para simular o método Fill, criei o seguinte para apoiar meus requisitos de simulação.Ainda não responde por que o conjunto de dados não foi substituído pelo meu conjunto de dados mole.
[TestMethod]
[HostType("Moles")]
public void IsolatedSqlDataAdaptorTestWithFill()
{
// Arrange
MSqlConnection.AllInstances.Open = c => { };
MSqlConnection.AllInstances.Close = c => { };
MSqlDataAdapter.ConstructorStringSqlConnection = (@this, cmd, conn) => { };
MDbDataAdapter.AllInstances.FillDataSetString = (da, ds, s) =>
{
var dt = new DataTable(s);
dt.Columns.Add(new DataColumn("string", typeof(string)));
dt.Columns.Add(new DataColumn("int", typeof(int)));
dt.Rows.Add("field", 5);
ds.Tables.Add(dt);
return 1;
};
// Act
using (var dset = new DataSet())
{
using (var conn = new SqlConnection())
{
using (var da = new SqlDataAdapter("select something from aTable", conn))
{
da.Fill(dset, "aTable");
}
}
// Assert
Assert.AreEqual(1, dset.Tables[0].Rows.Count, "Count");
Assert.AreEqual("field", dset.Tables[0].Rows[0]["string"], "string");
Assert.AreEqual(5, dset.Tables[0].Rows[0]["int"], "int");
}
}