我有一个我的大多数服务继承的baseService类,看起来像这样。
public abstract class BaseService<T> : IBaseService<T>
where T : class, IBaseEntity
{
protected IDataContext _context;
protected IValidator<T> _validator = null;
protected BaseService(IDataContext context)
{
_context = context;
}
protected BaseService(IDataContext context, IValidator<T> validator)
: this(context)
{
_validator = validator;
}
public virtual async Task<ICollection<T>> GetAllAsync()
{
return await _context.Set<T>().ToListAsync();
}
public virtual Task<T> GetAsync(long id)
{
return _context.Set<T>().Where(e => e.Id == id).FirstOrDefaultAsync();
}
public virtual Task<ValidationResult> ValidateAsync(T t)
{
if (_validator == null) throw new MissingFieldException("Validator does not exist for class " + t.GetType().ToString() + ". override method if no validation needed");
return _validator.ValidateAsync(t);
}
public virtual async Task<int> AddAsync(T t)
{
var results = await ValidateAsync(t);
if (!results.IsValid) {
throw new ValidationException(results.Errors);
}
if (_context.GetState(t) == EntityState.Detached)
{
_context.Set<T>().Add(t);
_context.SetState(t, EntityState.Added);
}
return await _context.SaveChangesAsync();
}
public virtual async Task<int> UpdateAsync(T updated)
{
var results = await ValidateAsync(updated);
if (!results.IsValid)
{
throw new ValidationException(results.Errors);
}
if (_context.GetState(updated) == EntityState.Detached)
{
_context.SetState(updated, EntityState.Modified);
}
return await _context.SaveChangesAsync();
}
public virtual Task<int> DeleteAsync(T t)
{
_context.SetState(t, EntityState.Deleted);
return _context.SaveChangesAsync();
}
}
我是否正确地认为在我的每个实现此服务的类中进行单元测试是没有意义的?但是,在集成测试中测试每个测试的功能吗?
答案 0 :(得分:3)
如果您选择composition over inheritance,那么您可以避免该决定,也就是说,您将其创建为具有IBaseService作为依赖关系,而不是您从BaseService继承的服务,例如
public class MyService
{
private readonly IBaseService<SomeBaseIdentity> _service;
public MyService(IBaseService<SomeBaseIdentity> service)
{
_service = service;
}
//.... methods that use _service
}
通过这种方式,您可以使用隔离框架(Rhino Mocks,Moq等)测试MyService,而无需担心IBaseService的实际实现。
关于选择组合而不是继承的这个主题已经写了很多。其中绝大多数意味着它是一种优越的方法(主要是因为它更灵活,即如果使用组合可以交换实现,而如果使用继承,则所有派生类都会在更改的意义上与基类绑定到基类影响所有派生类),到Java语言创建者的意思是说如果可以的话,他会disallow it in Java。