我已尝试过几种方法对REST服务进行单元测试,但无济于事。
关注this帖子,通过创建DirectServiceClient但“方法未实现”引发异常。
直接实例化Web服务并调用Any()方法,它可以工作,但它可以访问数据库。我已在设置中初始化连接,如下所示。但我不知道如何模拟连接对象并设置内存中的客户对象。
_dbConnection = new OrmLiteConnectionFactory(TestConfig.ConnectionString,SqlServerDialect.Provider).OpenDbConnection();
任何人都可以提供一些关于如何在这种情况下编写单元测试的输入。
客户服务
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;
}
}
请求
[Route("/customers")]
[Route("/customer/{id}")]
public class CustomerRequest : IReturn<Customer>
{
public string id { get; set; }
}
答案 0 :(得分:3)
我相信DirectServiceClient更多地用于集成测试(即端到端)。
使用模拟工具来存根数据库。毕竟,对于此单元测试,您只想测试“任何”方法:
[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)); }
大概是这样的。 (抱歉abt格式化...... SOO格式化程序没有表现,所以我阻止引用它)
答案 1 :(得分:2)
这是我可以为此方法编写的唯一测试。
ozczehco的回答将测试抛出异常的代码路径。如果要测试超出异常的代码路径,则需要模拟/存根_dbConnection.QueryDapper调用。
下面是通过添加测试'Any_CalledWithAnId_ReturnsCustomer()'来扩展ozczecho答案,并包括所有'仪式'。我确实修改了你提供的代码中的一些内容。我没有为新测试模拟/存根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();
}
}