首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ServiceStack服务的单元测试

ServiceStack服务的单元测试
EN

Stack Overflow用户
提问于 2013-03-20 04:57:39
回答 1查看 1.2K关注 0票数 4

我正在尝试为ServiceStack服务编写简单的单元测试,我正在通过他们在线的测试和这里的一些线程。这是我试图实现的具有最多细节的主线程-- Unit Test HTTPRequest Headers with ServiceStack

然而,我面临着将IDbConnection对象注入到服务中的问题。在webmethod中,字典对象是使用OrmLite的GetDictionary方法填充的。但我无法模仿它,因为GetDictionary是扩展方法。

代码语言:javascript
复制
 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."}
    };
}

测试方法中

代码语言:javascript
复制
 var service = new CustomerLookupService(_dbConnectionMock.Object);
 var response = (HttpResult)service.Any(new CustomerLookup { name = "test" });
 //assert statements

如果GetDictionary方法不能被模仿,我甚至愿意调用命中DB的web方法,为此我需要创建AppHost。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-20 06:28:25

我认为有几个选择可以考虑。

  • Mocking/stubbing/unit-testing扩展方法herehere或各种其他点。我不认为有一个更好的方法可以做到这一点,但是有一些选项和框架/库可以帮助你。
  • 运行一个内存中的数据库,比如Sqlite来进行单元测试。here.
  • You可以将IDConnection抽象为CustomerLookUpRepository,并将CustomerLookUpRepository注入到您的服务中。然后你就可以模拟你的“仓库”了。

我已经试过这个“安排”了。到目前为止,它似乎适用于大多数基本情况。数据访问模式取自Redis Web Service example。不过,YMMV。

测试(使用RhinoMocks)

代码语言:javascript
复制
    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作为参数,因此我不必编写几个方法来访问数据库。

代码语言:javascript
复制
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

代码语言:javascript
复制
public interface ISqlRepository
{
    T Exec<T>(Func<IDbConnection, T> fn);
}

SqlRepository

代码语言:javascript
复制
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);
        }
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15510292

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档