Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无意义单元测试_C#_Asp.net_.net_Entity Framework_Unit Testing - Fatal编程技术网

C# 无意义单元测试

C# 无意义单元测试,c#,asp.net,.net,entity-framework,unit-testing,C#,Asp.net,.net,Entity Framework,Unit Testing,我有一个baseService类,我的大多数服务都是从该类继承的,如下所示 public abstract class BaseService<T> : IBaseService<T> where T : class, IBaseEntity { protected IDataContext _context; protected IValidator<T> _validator = null; protected BaseS

我有一个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();
    }
}
公共抽象类BaseService:IBaseService
其中T:类,IBaseEntity
{
受保护的IDataContext\u上下文;
受保护的IValidator _验证程序=null;
受保护的BaseService(IDataContext上下文)
{
_上下文=上下文;
}
受保护的BaseService(IDataContext上下文、IValidator验证器)
:此(上下文)
{
_验证器=验证器;
}
公共虚拟异步任务GetAllAsync()
{
返回wait_context.Set().ToListAsync();
}
公共虚拟任务GetAsync(长id)
{
返回_context.Set(),其中(e=>e.Id==Id).FirstOrDefaultAsync();
}
公共虚拟任务ValidateAsync(T)
{
如果(_validator==null)抛出新的MissingFieldException(“类“+t.GetType().ToString()+”的验证器不存在。如果不需要验证,则重写方法”);
返回_validator.ValidateAsync(t);
}
公共虚拟异步任务AddAsync(T)
{
var结果=等待验证同步(t);
如果(!results.IsValid){
抛出新的ValidationException(results.Errors);
}
if(_context.GetState(t)=EntityState.Detached)
{
_context.Set().Add(t);
_SetState(t,EntityState.Added);
}
return wait_context.saveChangesSync();
}
公共虚拟异步任务UpdateAsync(T已更新)
{
var结果=等待验证同步(更新);
如果(!results.IsValid)
{
抛出新的ValidationException(results.Errors);
}
if(_context.GetState(updated)=EntityState.Detached)
{
_SetState(已更新,EntityState.Modified);
}
return wait_context.saveChangesSync();
}
公共虚拟任务DeleteAsync(T)
{
_SetState(t,EntityState.Deleted);
返回_context.SaveChangesAsync();
}
}

我认为在实现此服务的每一个类中进行单元测试毫无意义,这是对的吗?但是,相反,在我的集成测试中测试每个测试的功能?

如果您选择,您可以避免这个决定,也就是说,您的服务不是从BaseService继承的,而是将IBaseService作为一个依赖项来创建它们

public class MyService 
{
  private readonly IBaseService<SomeBaseIdentity> _service;

  public MyService(IBaseService<SomeBaseIdentity> service)
  {
    _service = service;
  }

  //.... methods that use _service
}
公共类MyService
{
专用只读IBaseService\u服务;
公共MyService(IBaseService服务)
{
_服务=服务;
}
//..使用_服务的方法
}
通过这种方式,您可以使用隔离框架(Rhino Mocks、Moq等)测试MyService,而不用担心IBaseService的实际实现


关于选择组合而不是继承这一主题,已经有很多文章发表了。其中绝大多数意味着它是一种优越的方法(主要是因为它更灵活,即如果使用组合,可以交换实现,而如果使用继承,则所有派生类都与基类绑定,因为基类的更改会影响所有派生类),Java语言的创建者说如果可以,他会的。

真的很难说。我要测试的方法不仅仅是LINQ周围的Fascade。A插入诸如抛出异常和实体状态之类的内容。其余的都没有意义。。在那之后,您将基本上测试LINQ。由于方法是虚拟的,我将测试它们,因为谁知道某个派生类何时会覆盖它,但在验证失败时未能抛出,或者调用
ValidateAsync
等失败。如果不是虚拟的,你只能测试一个派生类,它基本上涵盖了所有的方法。我个人会测试它们。为了简化该任务,您可以为每个装置创建一个基类,使用模板方法工厂方法创建SUT的具体实现,测试基类公共方法,或者编写类似AutoFixture的习语,基本上是一个测试基类的类。那么,将其编写为BaseUnitTest并从该基类继承单元测试以测试此功能的观点是什么?一遍又一遍地编写相同的测试似乎是在浪费时间。你真的重写了这些方法吗?或者扩展,因为它似乎已经包装了所有的积垢。如果不是,为什么要把它抽象起来呢?我想我会尝试一下,因为大多数时候我都想在基类中使用AddAsync和其他函数,所以单元测试“调用”似乎毫无意义。但是在我重写该方法的其他类中,我希望对其进行单元测试。也许组合更适合这里。那么你如何为myservice编写一个单元测试,并说另一个名为MyService2的服务使用组合而不是InHirtance?我会为每个服务编写一个单元测试,不过我会使用IBaseService的存根/模拟(这些名称让人困惑,将IBaseService视为一个依赖项,例如IRepository)。如果您对此不熟悉,。既然您提出了建议,我已经采纳了您的建议。这是正确的吗?似乎编译正常,但simple injector现在在注入IEntityBaseService时会抛出错误,我猜是因为它是通用的。您介意看一下吗?