Unit testing 单元测试ServiceStack REST Web服务
我尝试了几种方法对REST服务进行单元测试,但都没有效果Unit testing 单元测试ServiceStack REST Web服务,unit-testing,servicestack,Unit Testing,servicestack,我尝试了几种方法对REST服务进行单元测试,但都没有效果 在post之后,创建DirectServiceClient,但引发了“方法未实现”异常 直接实例化web服务并调用Any()方法,它可以工作,但会命中数据库。我已经在设置中初始化了连接,如下所示。但我不知道如何模拟连接对象并在内存中设置客户对象 _dbConnection=new或mliteConnectionFactory(TestConfig.ConnectionString,sqlserverdialent.Provider) 有人
public class CustomerService : Service
{
private readonly IDbConnection _dbConnection;
public CustomerService(IDbConnection dbConnection)
{
_dbConnection = dbConnection;
}
public object Any(CustomerRequest request)
{
if (request.id == null)
{
throw new ArgumentException("id is required");
}
var customer = _dbConnection.QueryDapper<Customer>("getCustomer",new {@id=request.id}).ToList();
return customer;
}
}
公共类客户服务:服务
{
专用只读IDBConnectionu dbConnection;
公共客户服务(IDbConnection dbConnection)
{
_dbConnection=dbConnection;
}
任何公共对象(CustomerRequest请求)
{
if(request.id==null)
{
抛出新ArgumentException(“需要id”);
}
var customer=_dbConnection.QueryDapper(“getCustomer”,new{@id=request.id}).ToList();
退货客户;
}
}
请求
[Route("/customers")]
[Route("/customer/{id}")]
public class CustomerRequest : IReturn<Customer>
{
public string id { get; set; }
}
[路线(“/customers”)]
[路由(“/customer/{id}”)]
公共类CustomerRequest:IReturn
{
公共字符串id{get;set;}
}
[测试]
public void Any_调用而没有ID_ExpectThrowArgumentException()
{
var db=MockRepository.GenerateStub();
var request=new CustomerRequest();
var服务=新客户服务(db);
抛出(()=>service.Any(请求));
}
大致就是这样。(很抱歉,abt格式化…SOO格式化程序无法运行,因此我将其引用)这是我可以为该方法编写的唯一测试。 ozczehco的回答将测试引发异常的代码路径。如果要测试通过异常的代码路径,则需要模拟/存根_dbConnection.QueryDapper调用 下面是ozczecho答案的扩展,添加了一个测试“Any_CalledWithAnId_returnsCastomer()”,包括所有的“仪式”。我确实修改了您提供的代码中的一些内容。我没有为新测试模拟/存根IDbConnection,而是创建了一个InMemoryTestDatabase用于测试不要对您自己的数据库使用此选项,因为它会清除测试的“客户”表
[TestFixture]
public class CustomerServiceTest
{
public IDbConnectionFactory InMemoryTestDatabase;
[SetUp]
public void SetUp()
{
InMemoryTestDatabase = new OrmLiteConnectionFactory("c:\\testData.db", SqliteDialect.Provider);
}
[Test]
public void Any_CalledWithoutId_ExpectThrowArgumentException()
{
var db = MockRepository.GenerateStub<IDbConnection>();
var request = new CustomerRequest();
var service = new CustomerService(db);
Assert.Throws<ArgumentException>(() => service.Any(request));
}
[Test]
public void Any_CalledWithAnId_ReturnsCustomer()
{
//Arrange your data
long requestId;
using (var con = InMemoryTestDatabase.OpenDbConnection())
{
con.CreateTable<Customer>(true); //Force drop to create clean table and data
con.Insert<Customer>(new Customer { FirstName = "Johnny", LastName = "Test"});
requestId = con.GetLastInsertId();
}
//Act
var request = new CustomerRequest {id = (int)requestId};
var service = new CustomerService(InMemoryTestDatabase.OpenDbConnection());
var result = (Customer)service.Any(request);
//Assert
Assert.AreEqual(requestId, result.Id);
Assert.AreEqual("Johnny", result.FirstName);
}
}
[Route("/customers")]
[Route("/customer/{id}")]
public class CustomerRequest : IReturn<Customer>
{
public long id { get; set; }
}
public class Customer
{
[AutoIncrement]
public long Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class CustomerService : ServiceStack.ServiceInterface.Service
{
private readonly IDbConnection _dbConnection;
public CustomerService(IDbConnection dbConnection)
{
_dbConnection = dbConnection;
}
public object Any(CustomerRequest request)
{
if (request.id == null)
{
throw new ArgumentException("id is required");
}
var customer = _dbConnection.QueryDapper<Customer>("Select * From Customer Where Id = @id", new { id = request.id }).ToList();
return customer.FirstOrDefault();
}
}
[TestFixture]
公共类CustomerServiceTest
{
MemoryTestDatabase中的公共IDbConnectionFactory;
[设置]
公共作废设置()
{
InMemoryTestDatabase=new或mliteConnectionFactory(“c:\\testData.db”,sqlitedialent.Provider);
}
[测试]
public void Any_调用而没有ID_ExpectThrowArgumentException()
{
var db=MockRepository.GenerateStub();
var request=new CustomerRequest();
var服务=新客户服务(db);
抛出(()=>service.Any(请求));
}
[测试]
public void Any_CalledWithAnId_ReturnsCustomer()
{
//整理数据
长请求ID;
使用(var con=InMemoryTestDatabase.OpenDbConnection())
{
con.CreateTable(true);//强制拖放以创建干净的表和数据
con.Insert(新客户{FirstName=“Johnny”,LastName=“Test”});
requestId=con.GetLastInsertId();
}
//表演
var request=newcustomerrequest{id=(int)requestId};
var service=newcustomerservice(InMemoryTestDatabase.OpenDbConnection());
var结果=(客户)服务。任何(请求);
//断言
arenequal(requestId,result.Id);
Assert.AreEqual(“Johnny”,result.FirstName);
}
}
[路线(“/客户”)]
[路由(“/customer/{id}”)]
公共类CustomerRequest:IReturn
{
公共长id{get;set;}
}
公共类客户
{
[自动增量]
公共长Id{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
}
公共类CustomerService:ServiceStack.ServiceInterface.Service
{
专用只读IDBConnectionu dbConnection;
公共客户服务(IDbConnection dbConnection)
{
_dbConnection=dbConnection;
}
任何公共对象(CustomerRequest请求)
{
if(request.id==null)
{
抛出新ArgumentException(“需要id”);
}
var customer=_dbConnection.QueryDapper(“Select*From customer,其中Id=@Id”,new{Id=request.Id})。ToList();
返回customer.FirstOrDefault();
}
}
这是我能为这种方法编写的唯一测试。很抱歉,我不熟悉TDD,也不知道如何检查属性是否正确映射到CustomerTo。我的意思是如何模拟数据库中的数据。谢谢你的回答!我正在调用不同数据库中的存储过程来填充DTO,所以如何使用内存中的数据库执行此操作。我不知道hink Sqlite支持存储过程-。您可以创建一个仅用于测试的数据库,而不是内存中的数据库。
[TestFixture]
public class CustomerServiceTest
{
public IDbConnectionFactory InMemoryTestDatabase;
[SetUp]
public void SetUp()
{
InMemoryTestDatabase = new OrmLiteConnectionFactory("c:\\testData.db", SqliteDialect.Provider);
}
[Test]
public void Any_CalledWithoutId_ExpectThrowArgumentException()
{
var db = MockRepository.GenerateStub<IDbConnection>();
var request = new CustomerRequest();
var service = new CustomerService(db);
Assert.Throws<ArgumentException>(() => service.Any(request));
}
[Test]
public void Any_CalledWithAnId_ReturnsCustomer()
{
//Arrange your data
long requestId;
using (var con = InMemoryTestDatabase.OpenDbConnection())
{
con.CreateTable<Customer>(true); //Force drop to create clean table and data
con.Insert<Customer>(new Customer { FirstName = "Johnny", LastName = "Test"});
requestId = con.GetLastInsertId();
}
//Act
var request = new CustomerRequest {id = (int)requestId};
var service = new CustomerService(InMemoryTestDatabase.OpenDbConnection());
var result = (Customer)service.Any(request);
//Assert
Assert.AreEqual(requestId, result.Id);
Assert.AreEqual("Johnny", result.FirstName);
}
}
[Route("/customers")]
[Route("/customer/{id}")]
public class CustomerRequest : IReturn<Customer>
{
public long id { get; set; }
}
public class Customer
{
[AutoIncrement]
public long Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class CustomerService : ServiceStack.ServiceInterface.Service
{
private readonly IDbConnection _dbConnection;
public CustomerService(IDbConnection dbConnection)
{
_dbConnection = dbConnection;
}
public object Any(CustomerRequest request)
{
if (request.id == null)
{
throw new ArgumentException("id is required");
}
var customer = _dbConnection.QueryDapper<Customer>("Select * From Customer Where Id = @id", new { id = request.id }).ToList();
return customer.FirstOrDefault();
}
}