[英]Unit tests for ServiceStack services
我正在嘗試為ServiceStack服務編寫簡單的單元測試,我正在通過測試他們在線和幾個線程。 這是我想要完成的大部分細節的主線程 - 使用ServiceStack進行單元測試HTTPRequest標頭 。
但是,我遇到了將IDbConnection對象注入服務的問題。 在web方法中,使用OrmLite的GetDictionary方法填充字典對象。 但是我無法模仿它,因為GetDictionary是擴展方法。
private Mock<IDbConnection> _dbConnectionMock;
private Dictionary<string, string> _nameValuePairs;
[SetUp]
public void SetUp()
{
_dbConnectionMock = new Mock<IDbConnection>();
_nameValuePairs = new Dictionary<string, string>()
{
{"name","test"},
{"Updatedby", "5/23/12 7:00:15 AM"},
{"Address", "212 Adam St."}
};
}
在測試方法
var service = new CustomerLookupService(_dbConnectionMock.Object);
var response = (HttpResult)service.Any(new CustomerLookup { name = "test" });
//assert statements
如果無法模擬GetDictionary方法,我甚至願意調用命中DB的web方法,為此我需要創建AppHost。
我認為有幾個選項可供研究。
模擬/存根/單元測試擴展方法在這里 , 這里或其他各種點。 我不認為有一種首選方法可以做到這一點,但有一些選項和框架/庫可以提供幫助。
運行內存數據庫(如Sqlite)進行單元測試。 看到這里 。
您可以將IDConnection抽象為CustomerLookUpRepository,並將CustomerLookUpRepository注入您的服務。 然后你可以模擬你的'存儲庫'。
我試試這個'安排'。 到目前為止,它似乎適用於大多數基本情況。 數據訪問模式來自Redis Web Service示例 。 但是YMMV。
測試 (使用RhinoMocks)
public void SomeTest()
{
var _nameValuePairs = new Dictionary<string, string>()
{
{"name","test"},
{"Updatedby", "5/23/12 7:00:15 AM"},
{"Address", "212 Adam St."}
};
var mockSqlRepository = MockRepository.GenerateMock<ISqlRepository>();
mockSqlRepository.Stub(
x => x.Exec(Arg<Func<IDbConnection, Dictionary<string, string>>>.Is.NotNull)).Return(_nameValuePairs);
var service = new CustomerLookupService { SqlRepository = mockSqlRepository }
//MORE TEST CODE...
}
服務類 - 使用ISqlRepository抽象/隱藏IDbConnection。 ISqlRepository有一個函數,它將函數作為參數。 函數簽名(參數)將IDbConnection作為參數,因此我不必編寫幾種方法來訪問數據庫。
public class CustomerLookupService
{
public ISqlRepository SqlRepository { get; set; }
public void Any(CustomerLookup request)
{
var results =
SqlExec<Dictionary<string, string>>((con) => con.GetDictionary<type, type>("Select id, name from table"));
//MORE SERVICE CODE
}
public T SqlExec<T>(Func<IDbConnection, T> fn)
{
return SqlRepository.Exec(fn);
}
}
ISqlRepository
public interface ISqlRepository
{
T Exec<T>(Func<IDbConnection, T> fn);
}
SqlRepository
public class SqlRepository : ISqlRepository
{
public IDbConnectionFactory DbFactory { get; set; }
public T Exec<T>(Func<IDbConnection, T> fn)
{
using (var con = DbFactory.OpenDbConnection())
{
return fn(con);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.