c# - 如何对依赖于工厂的代码进行单元测试

标签 c# unit-testing factory

我有一个如下所示的 DataService 类

public class LessonDataService
{

    IUnitOfWork unitOfWork = UnitOfWorkFactory.CreateUnitOfWork();

    public Lesson FindById(int id)
    {
        try
        {
            return unitOfWork.Lessons.FindById(id);
        }
        catch (Exception ex)
        {
            throw exception;
        }
    }
}

正如您所看到的,UnitOfWork 是在 DataService 类内部构造的。我也不希望通过构造函数传递 UnitOfWork,我不希望 UI 代码打扰 UnitOfWork,我只希望它调用 DataService 类并让它完成其余的工作。有什么想法吗?

最佳答案

How to unit test code that depends on a Factory

简短回答:你不

Abstract Factories are a code smell

紧密耦合的代码很难测试。 (但并非不可能)。

通过构造函数注入(inject)重构代码以实现显式依赖。 (避免服务定位器反模式)

public class LessonDataService : ILessonDataService {    
    private readonly IUnitOfWork unitOfWork;

    public LessonDataService(IUnitOfWork unitOfWork) {
        this.unitOfWork = unitOfWork;
    }

    public Lesson FindById(int id) {
        try {
            return unitOfWork.Lessons.FindById(id);
        } catch (Exception ex) {
            throw exception;
        }
    }
}

I don't want the UI code to bother with UnitOfWork I just want it to call the DataService class and let it do the rest.

然后抽象服务,将其注入(inject)到 UI 中并让它完成其余的工作。 UI 不应直接与 UOW 相关。

public interface ILessonDataService  {
    Lesson FindById(int id);
}

通过重构以依赖于显式抽象,代码现在更加灵活,并且可以单独测试,并且负面影响最小。

[TestMethod]
public void DataService_Should_Get_Lesson() {
    //Arrange
    var id = 1;
    var lesson = new Lesson {
        Id = id,
        //...code removed for brevity
    };
    var mock = new Mock<IUnitOfWork>();
    mock.Setup(_ => _.Lessons.FindById(id)).Returns(lesson);

    var sut = new LessonDataService(mock.Object);

    //Act
    var actual = sut.FindById(id);

    //Assert
    lession.Should().BeEquivalentTo(actual);
}

在生产代码中,当前工厂仍然可以在组合根中的 DI 容器中注册,但仍保持代码解耦。

例如(在.Net Core中)

services.AddTransient<IUnitOfWork>(_ => UnitOfWorkFactory.CreateUnitOfWork());
services.AddTransient<ILessonDataService, LessonDataService>();

关于c# - 如何对依赖于工厂的代码进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46428747/

相关文章:

c# - 在 Windows 7 下为非管理员用户提供目录的完全控制

java - 用于数据库代码的 JUnit

java - 如何为不同的测试上下文重用 JUnit 测试方法?

c# - 是否值得为单个类抽象出对象创建?

ruby-on-rails - rspec 测试的 JSON 数据

c# - Outlook 2013 加载项安装后未加载

c# - 我如何找到元素颜色;切换时我需要检查的元素会更改颜色

c# - 当我什么都得不到时却得到空洞的答案

objective-c - NSBundle pathForResource 返回 nil

c++ - 使用boost factory按需生产产品C++