我正在尝试使用Sqlite为ServiceStack服务编写单元测试。由于Sqlite不支持存储过程,我创建了'ServiceCommand'类型的公共属性,它将命令文本和命令类型作为输入。默认情况下,它配置为运行存储过程,在编写单元测试用例时,我在调用Any()
方法之前将SelectCommand属性重新分配给sqlite进行sql查询,如下所示。所有测试用例都运行良好。
var request = new CustomerRequest() { name = "alfki" };
var service = new CustomerService(InMemoryTestDatabase.OpenDbConnection());
service.SelectCommand = new ServiceCommand() { SQL = "SELECT * FROM customers where customerid = {0}" };
var result = service.Any(request);
但根据此thread,IOC在解析引用时将CustomerService的公共属性设置为null,因此Any()
方法中的SelectCommand为空,从而导致对象引用错误。通过将属性设置为protected,private,internal或static,我将无法运行单元测试。
public class CustomerService : Service
{
private readonly IDbConnection _dbConnection;
public ServiceCommand SelectCommand {get;set;}
public CustomerService(IDBConnection dbConnection)
{
_dbConnection = dbConnection; //injected successfully
SelectCommand = new ServiceCommand(){ SQL = "sp_getcustomers",
CommandType = CommandType.StoredProcedure};
}
public Customer Any(CustomerRequest request)
{
//Select command is not accessible here.
}
}
[Route("/customers")]
public class CustomerRequest
{
public string name { get; set; }
}
ServiceCommand
public class ServiceCommand
{
public string SQL { get; set; }
public CommandType CommandType { get; set; }
public ServiceCommand()
{
CommandType = CommandType.Text;
}
}
为了能够运行测试用例和服务,我修改了Any()
方法来实例化ServiceCommand,如果它是null。我想知道这是否可行,或者是否有更好的选择。
public class CustomerService : Service
{
private readonly IDbConnection _dbConnection; // injected successfully
public ServiceCommand SelectCommand {get;set;}
public CustomerService(IDBConnection dbConnection)
{
_dbConnection = dbConnection; //injected successfully
}
public Customer Any(CustomerRequest request)
{
SelectCommand = SelectCommand ?? new ServiceCommand() { SQL = "sp_getCustomers",CommandType = CommandType.StoredProcedure };
}
}
答案 0 :(得分:1)
由于ServiceStack服务将为所有公共属性注入已注册的IOC属性,它将覆盖您在构造函数中设置的值,因此如果不在IOC中注册它,则无法将其设置为公共属性,因为它将被覆盖为空。
鉴于此,一些可能的选择是:
public class CustomerService : Service
{
public ServiceCommand SelectCommand = new ServiceCommand {
SQL = "sp_getcustomers",
CommandType = CommandType.StoredProcedure };
...
}
service.SetSelectCommand(
new ServiceCommand { SQL = "SELECT * FROM customers where customerid = {0}" });
container.Register(new ServiceCommand {
SQL = "sp_getcustomers",
CommandType = CommandType.StoredProcedure });
并将构造函数更改为:
public CustomerService(IDBConnection dbConnection, ServiceCommand serviceCommand)
{
_dbConnection = dbConnection;
_serviceCommand = serviceCommand;
}