當前被測方法與實現方面的問題緊密耦合,使得單元可以很容易地單獨測試。嘗試將這些實現問題抽象出來,以便它們可以輕鬆地進行孤立測試。
public interface IDbConnectionFactory {
IDbConnection CreateConnection();
}
上述連接工廠的抽象可用於訪問您的Oracle數據存儲的其他必要System.Data
抽象。
public class MyDataAccessClass {
private IDbConnectionFactory connectionFactory;
public MyDataAccessClass(IDbConnectionFactory connectionFactory) {
this.connectionFactory = connectionFactory;
}
public object GetData(string nuf) {
using (var connection = connectionFactory.CreateConnection()) {
connection.Open();
var query = "SELECT mi.* from fromTable mi where 1=1 "
+ (string.IsNullOrEmpty(nuf) ? "" : " and mi.NUF != @nuf")
+ " and mi.Category<>'TES' and mi.Category<>'CVD'"
using(var command = connection.CreateCommand()){
command.CommandText = query;
command.CommandType = CommandType.Text;
if(!string.IsNullOrEmpty(nuf)) {
var parameter = command.CreateParameter();
parameter.ParameterName = "@nuf";
parameter.Value = nuf;
command.Parameters.Add(parameter);
}
Debug.WriteLine(command.CommandText);
var dr = command.ExecuteReader();
//...other code removed for brevity
}
}
}
}
的生產實施工廠將返回的實際OracleConnection
public class OracleConnectionFactory: IDbConnectionFactory {
public IDbConnection CreateConnection() {
return new OracleConnection("connection string");
}
}
其可以通過依賴注入被傳遞到從屬類。
爲了測試你使用你選擇的模擬框架來模擬接口,或者創建自己的假貨來注入和測試你的方法。
[TestClass]
public class DataAccessLayerUnitTest {
[TestMethod]
public void TestFilter() {
//Arrange
var readerMock = new Mock<IDataReader>();
var commandMock = new Mock<IDbCommand>();
commandMock.Setup(m => m.ExecuteReader())
.Returns(readerMock.Object)
.Verifiable();
var parameterMock = new Mock<IDbDataParameter>();
commandMock.Setup(m => m.CreateParameter())
.Returns(parameterMock.Object);
commandMock.Setup(m => m.Parameters.Add(It.IsAny<IDbDataParameter>()))
.Verifiable();
var connectionMock = new Mock<IDbConnection>();
connectionMock
.Setup(m => m.CreateCommand())
.Returns(commandMock.Object);
var connectionFactoryMock = new Mock<IDbConnectionFactory>();
connectionFactoryMock
.Setup(m => m.CreateConnection())
.Returns(connectionMock.Object);
var sut = new MyDataAccessClass(connectionFactoryMock.Object);
var input = "some value";
//Act
var data = sut.GetData(input);
//Assert
commandMock.Verify();
}
}
最後,您使用的命令參數的命令文本與外在價值手動構建查詢字符串建議打開代碼最多SQL注入攻擊。
所以當你執行cmd時,你得到了什麼或者沒有得到什麼。也嘗試構建您的查詢要麼調用存儲過程,但儘量不要使用連接字符串來建立查詢..你正在設置自己的SQL注入。 – MethodMan
當然。稍後,我將從內聯SQL轉移到存儲過程。這可以查詢實際的數據庫。我想查詢內存中的數據並應用過濾器,以便我可以進行單元測試。 –
嘗試將數據作爲DataTable返回,並使用DataTables'Filer'函數。所以你可以查詢..有大量的工作例子,如何做到這一點以及在StackOverflow以及互聯網,如果你做一個'谷歌搜索在C#Stackoverflow DataTable.Filter'它會產生很多結果。 – MethodMan