Unit/Integration DAL 和 BLL 测试(使用 lambda)
Unit/Integration tests for DAL and BLL (with lambdas)
我的代码基本上是这样的:
数据访问合同:
public interface IProvideDataAccess<T>
where T : Entity
{
IEnumerable<T> Select(Func<T, bool> condition);
void Save(T entity);
void Delete(T entity);
}
数据访问层:
public class Db4oProvider<T> : IProvideDataAccess<T>
where T : Entity
{
private IEmbeddedConfiguration _configuration;
private string _connectionString;
public Db4oAccesDonnees(string connectionString)
{
_connectionString = connectionString;
_configuration = Db4oEmbedded.NewConfiguration();
}
IEnumerable<T> IProvideDataAccess<T>.Select(Func<T, bool> condition)
{
using (IObjectContainer db = Db4oEmbedded.OpenFile(_configuration, _connexion))
{
return db.Query<T>(e => condition(e));
}
}
void IProvideDataAccess<T>.Save(T entity)
{
using (IObjectContainer db = Db4oEmbedded.OpenFile(_configuration, _connexion))
{
db.Store(entity);
}
}
void IProvideDataAccess<T>.Delete(T entity)
{
using (IObjectContainer db = Db4oEmbedded.OpenFile(_configuration, _connexion))
{
db.Delete(entity);
}
}
}
业务逻辑层:
public class MyRepository
{
protected IProvideDataAccess<MyEntityType> _dataAccessProvider;
public MyRepository(IProvideDataAccess<MyEntityType> dataAccessProvider)
{
_dataAccessProvider = dataAccessProvider;
}
public IEnumerable<MyEntityType> SelectValidEntities()
{
return _dataAccessProvider.Select(e => /* test if entity is valid */);
}
}
Unit/Integration 测试对我来说相当陌生,我不知道从哪里开始。
我认为合乎逻辑的做法是
- 为 DAL 编写集成测试
- 为 BLL(使用假 DAL)编写单元测试
我这个正确吗?
我最大的问题是 "select" 方法及其 Func 参数。我如何 test/mock 那?
基本上,我应该为这两个写什么测试类?
你的 DAL
看起来像 classes,永远不会改变...在我看来,在它们上面创建 UT
或 IT
是浪费时间。您应该使用良好的组件/"large Integration"(不仅是单元 + 数据库)测试来覆盖 class 的行为,例如 Db4oProvider<T>
。我建议您阅读有关 Test Pyramid
(In Martin Fowler blog and this good article) 的内容。我喜欢下面的金字塔:
关于Select
方法:
在 Integration test
(unit + DB) 中,您必须将数据放入您的数据库中(或将数据保留在数据库中...),调用 Select
条件,然后验证您得到了预期的数据。
在Component test
中,您需要将其作为被测行为的一部分进行测试,如果测试成功,那么一切都很好...
在 UT
中,测试分为两种类型:
1.The 测试你验证传递给 Select
方法的条件(lambda)的行为:(这样你也验证了 Select
被正确调用参数...在我的示例中,我使用 RhinoMocks
)
var fakeProvider = MockRepository.GenerateStub<IProvideDataAccess<Entity>>();
fakeProvider.Select(o => o.Id =="asdfg");
fakeProvider.AssertWasCalled(access => access.Select(Arg<Func<Entity, bool>>
.Matches(func => func(new Entity()
{
Id = "asdfg"
}))));
2.The 测试验证调用方方法行为的位置。在这些测试中,您应该将 DAL
配置为 return 一些重要的参数是:
_selectResult = new List<Entity>();
fakeProvider.Stub(x => x.Select(Arg<Func<Entity, bool>>.Is.Anything))
.Return(_selectResult);
我的代码基本上是这样的:
数据访问合同:
public interface IProvideDataAccess<T>
where T : Entity
{
IEnumerable<T> Select(Func<T, bool> condition);
void Save(T entity);
void Delete(T entity);
}
数据访问层:
public class Db4oProvider<T> : IProvideDataAccess<T>
where T : Entity
{
private IEmbeddedConfiguration _configuration;
private string _connectionString;
public Db4oAccesDonnees(string connectionString)
{
_connectionString = connectionString;
_configuration = Db4oEmbedded.NewConfiguration();
}
IEnumerable<T> IProvideDataAccess<T>.Select(Func<T, bool> condition)
{
using (IObjectContainer db = Db4oEmbedded.OpenFile(_configuration, _connexion))
{
return db.Query<T>(e => condition(e));
}
}
void IProvideDataAccess<T>.Save(T entity)
{
using (IObjectContainer db = Db4oEmbedded.OpenFile(_configuration, _connexion))
{
db.Store(entity);
}
}
void IProvideDataAccess<T>.Delete(T entity)
{
using (IObjectContainer db = Db4oEmbedded.OpenFile(_configuration, _connexion))
{
db.Delete(entity);
}
}
}
业务逻辑层:
public class MyRepository
{
protected IProvideDataAccess<MyEntityType> _dataAccessProvider;
public MyRepository(IProvideDataAccess<MyEntityType> dataAccessProvider)
{
_dataAccessProvider = dataAccessProvider;
}
public IEnumerable<MyEntityType> SelectValidEntities()
{
return _dataAccessProvider.Select(e => /* test if entity is valid */);
}
}
Unit/Integration 测试对我来说相当陌生,我不知道从哪里开始。
我认为合乎逻辑的做法是
- 为 DAL 编写集成测试
- 为 BLL(使用假 DAL)编写单元测试
我这个正确吗?
我最大的问题是 "select" 方法及其 Func 参数。我如何 test/mock 那?
基本上,我应该为这两个写什么测试类?
你的 DAL
看起来像 classes,永远不会改变...在我看来,在它们上面创建 UT
或 IT
是浪费时间。您应该使用良好的组件/"large Integration"(不仅是单元 + 数据库)测试来覆盖 class 的行为,例如 Db4oProvider<T>
。我建议您阅读有关 Test Pyramid
(In Martin Fowler blog and this good article) 的内容。我喜欢下面的金字塔:
关于Select
方法:
在 Integration test
(unit + DB) 中,您必须将数据放入您的数据库中(或将数据保留在数据库中...),调用 Select
条件,然后验证您得到了预期的数据。
在Component test
中,您需要将其作为被测行为的一部分进行测试,如果测试成功,那么一切都很好...
在 UT
中,测试分为两种类型:
1.The 测试你验证传递给 Select
方法的条件(lambda)的行为:(这样你也验证了 Select
被正确调用参数...在我的示例中,我使用 RhinoMocks
)
var fakeProvider = MockRepository.GenerateStub<IProvideDataAccess<Entity>>();
fakeProvider.Select(o => o.Id =="asdfg");
fakeProvider.AssertWasCalled(access => access.Select(Arg<Func<Entity, bool>>
.Matches(func => func(new Entity()
{
Id = "asdfg"
}))));
2.The 测试验证调用方方法行为的位置。在这些测试中,您应该将 DAL
配置为 return 一些重要的参数是:
_selectResult = new List<Entity>();
fakeProvider.Stub(x => x.Select(Arg<Func<Entity, bool>>.Is.Anything))
.Return(_selectResult);