对在同一对象上调用另一个公共函数的函数进行单元测试的正确方法是什么?

Toh*_*hid 1 c# unit-testing design-patterns

虽然我知道这个问题/答案(单元测试一种调用另一种方法的方法),但仍然不确定什么是对同一类调用另一个公共方法的方法进行单元测试的最佳方法?

我做了一个示例代码(也可以在这里看到:dotnetfiddle.net/I07RMg)

public class MyEntity
{
    public int ID { get; set;}
    public string Title { get; set;}
}

public interface IMyService
{
    MyEntity GetEntity(int entityId);
    IEnumerable<MyEntity> GetAllEntities();
}

public sealed class MyService : IMyService
{
    IRepository _repository;

    public MyService(IRepository repository)
    {
        _repository = repository;
    }

    public MyEntity GetEntity(int entityId)
    {
        var entities = GetAllEntities();
        var entity = entities.SingleOrDefault(e => e.ID == entityId);

        if (entity == null)
        {
            entity = new MyEntity { ID = -1, Title = "New Entity" };
        }

        return entity;
    }

    public IEnumerable<MyEntity> GetAllEntities()
    {
        var entities = _repository.Get();

        //Some rules and logics here, like:

        entities = entities.Where(e => !string.IsNullOrEmpty(e.Title));
        return entities; // To broke the test: return new List<MyEntity>();
    }
}

public interface IRepository : IDisposable
{
    IEnumerable<MyEntity> Get();
}
Run Code Online (Sandbox Code Playgroud)

那么问题是如何编写仅测试内部逻辑的单元测试MyService.GetEntity(int)?(虽然GetEntity内部呼叫,GetAllEntities()但我不想测试后一个).

Mat*_*zer 6

我真的相信单元测试不是嘲弄同一类的方法.

当我们谈论单位时,我们应该参考你的软件的一部分.也就是说,你想要进行测试,GetEntity并且它GetAllEntities在引擎盖下调用的事实只是一个实现细节.

您真正需要的是确保在测试您的服务时,任何注入的依赖项(存储库,在域中协作的其他服务......)都应该用假货代替,以确保您只是测试您的服务,或者你将实施集成测试.

OP在一些评论中说...

我明白.唯一需要注意的是,如果GetAllEntities()中的逻辑失败,它也可能会破坏GetEntity()的单元测试.然后有点难以确定真正的错误所在的位置.

正如我之前在这个答案中所说,GetEntity调用GetAllEntities只是一个实现细节.就像你要重新实现(argh,copy-paste programming ...)GetAllEntities内部逻辑一样GetEntity.谁在乎.

实际上,如果GetEntity因为失败GetAllEntities,那么GetAllEntities自己的测试也会失败.你会先尝试解决什么测试?我怀疑,一旦你意识到GetEntities失败因为GetAllEntities并且GetAllEntities测试失败,你会直接去修复GetAllEntities测试,不是吗?

总而言之,你描述你的问题的方式,错误将会开启GetAllEntities,并且绝对可以预期任何其他依赖的方法GetAllEntities也会失败.