流利/富有表现力的构建器单元测试和IOC



我不得不承认,我对教科书课程的实际应用有点困惑。

在这里阅读这篇文章并观看Mark Seeman在Pluralsight上的视频,我理解使用构建器模式将构造与表示分开。

例如:

public class Employee
{
   public Employee(int id, string firstname, string lastname, DateTime birthdate, string street)
   {
    ....do stuff..
   }
} 

典型的单元测试将在"安排"部分中包含重复和额外的信息:

public class EmployeeTest
{
   [Test]
   public void Test1()
   { 
     // Arrange
     Employee emp = new Employee(1, "Joe", "Blow", new DateTime(1970, 1, 1), "Somewhere");
    }
   [Test]
   public void Test2()
   { 
     // Arrange
     Employee emp = new Employee(1, "Joe", "Blow", new DateTime(1970, 1, 1), "Somewhere");
    }
   [Test]
   public void Test3()
   { 
     // Arrange
     Employee emp = new Employee(1, "Joe", "Blow", new DateTime(1970, 1, 1), "Somewhere");
    }
 }

使用流利/表达,我们将有一个用于安排的构建器,因此我们的测试将是

public class EmployeeTest
{
   [Test]
   public void GetFullNameReturnsCombination()
   { 
      // Arrange
      Employee emp = new EmployeeBuilder().WithFirstName("Joe").WithLastName("Blow");
   }
}

现在这如何适用于我的世界?

在实际应用程序中,我们将Ninject用于IOC,但我不确定如何将它与构建器模式结合使用。

假设我的构造函数是这样的:

public Employee(IDepartment _department, IFacility _facility)

在单元测试生成器模式实现中,我的"构建"是否会像往常一样挂接/注册到 Ninject?

public class EmployeeBuilder
{
  public Employee Build()
  {
    return new Employee(IDepartment _department, IFacility _facility);
  }
}

或者我会在 EmployeeBuiler.Build 中使用最小起订量?毕竟,单元测试的想法是它只能在单个"单元"上运行,而不必启动整个 SUT?

所以要明确的问题是我如何使用 IOC 的构建器模式创建单元测试,或者 Moq 如何适应......还是 Moq 类似于仅使用 Lambda 的流畅构建器模式?

首先,我认为你不应该在你的单元测试中使用NInject。在我看来,使用构建器模式,单元测试看起来像:(使用伪模拟)

public class EmployeeBuilder
{
    IFacility facility;
    IDepartment department;        
    public Employee Build()
    {
         return new Employee(IDepartment _department, IFacility _facility);
    }
    public EmployeeBuilder WithDepartment(IDepartment _department)
    {
        this.department = department;
        return this;
    }
    public EmployeeBuilder WithFacility(IFacility _facility)
    {
        this.facility = facility;
        return this;
    }
    public static implicit operator Employee(EmployeeBuilder instance)
    {
        return instance.Build();
    }
}
[TestFixture]
public class Tests
{
    [Test]
    public void Test1()
    {
        IFacility facility= MOCK(IFacility);
        IDepartment department= MOCK(IDepartment);
        Employee employee = new EmployeeBuilder().WithFacility(facility).WithDepartment(department);
        [exercise]
        [asserts]
    }
}

希望我有帮助

最新更新