2

I've tried couple of approaches to unit test the REST service but to no avail.

  1. Followed this post, by creating DirectServiceClient but "method is not implemented" exception is raised.

  2. Directly instantiated the web service and called the Any() method, it worked but it hits the DB. I've initialized the connection in the setup as below. But I am not knowing how to Mock connection object and set in-memory customer object.

    _dbConnection = new OrmLiteConnectionFactory(TestConfig.ConnectionString,SqlServerDialect.Provider).OpenDbConnection();

Could anyone provide some inputs on how to write unit tests in this kind of scenario.

Customer Service

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;
   }
}

Request

[Route("/customers")]
[Route("/customer/{id}")]
public class CustomerRequest : IReturn<Customer>
{
    public string id { get; set; }
}
4

2 回答 2

3
  1. 我相信 DirectServiceClient 更多地用于集成测试(即端到端)。

  2. 使用模拟工具来存根数据库。毕竟,对于这个单元测试,您只想测试“任何”方法:

[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));
}

大致就是这样。(对不起,格式化.... SOO 格式化程序不正常,所以我阻止引用它)

于 2013-03-26T22:16:00.400 回答
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();
    }
}
于 2013-03-27T23:14:22.170 回答