使用DI进行单元测试

时间:2016-09-06 12:56:52

标签: unit-testing dependency-injection

我理解使用DI作为依赖项并将它们模拟为单元测试。但是,当我有多个当前功能的实现时,我正在进行单元测试,如何将它们注入到单元测试中。

Ex:QuickSort或MergeSort

public class TestSort
{
  ISort sort = null;
    [TestInitialize]
    public void Setup()
    {
        sort = new MergeSort(); // or any implementation which need to be injected on setup
    }

1 个答案:

答案 0 :(得分:3)

如果你想测试你的"排序"方法,你应该为每个排序算法分别进行单元测试。例如

[TestMethod]
public void MergeSort_SortUnderorderedList_ShouldSortListCorrectly()
{
   // Arrange
   ISort sort = new MergeSort();

   // Act
   int[] sortedList = sort.Sort(new int[] { 4, 2, 18, 5, 19 });

   // Assert
   Assert.AreEqual(2, sortedList[0]);
   Assert.AreEqual(4, sortedList[1]);
   Assert.AreEqual(5, sortedList[2]);
   Assert.AreEqual(18, sortedList[3]);
   Assert.AreEqual(19, sortedList[4]);      
}

[TestMethod]
public void QuickSort_SortUnderorderedList_ShouldSortListCorrectly()
{
   // Arrange
   ISort sort = new QuickSort();

   // Act
   int[] sortedList = sort.Sort(new int[] { 4, 2, 18, 5, 19 });

   // Assert
   Assert.AreEqual(2, sortedList[0]);
   Assert.AreEqual(4, sortedList[1]);
   Assert.AreEqual(5, sortedList[2]);
   Assert.AreEqual(18, sortedList[3]);
   Assert.AreEqual(19, sortedList[4]);   
}

当你为一个注入排序算法的类编写测试时,你不应该测试排序算法是否在该测试中正常工作。相反,您应该注入一个排序算法mock并测试Sort()方法被调用(但不测试该测试中排序算法的正确结果)。

此示例使用Moq进行模拟

public class MyClass
{
   private readonly ISort sortingAlgorithm;

   public MyClass(ISort sortingAlgorithm)
   {
      if (sortingAlgorithm == null)
      {
         throw new ArgumentNullException("sortingAlgorithm");
      }
      this.sortingAlgorithm = sortingAlgorithm;
   }

   public void DoSomethingThatRequiresSorting(int[] list)
   {
      int[] sortedList = this.sortingAlgorithm.Sort(list);

      // Do stuff with sortedList
   }
}

[TestClass]
public class MyClassTests
{
   [TestMethod]
   public void DoSomethingThatRequiresSorting_SomeCondition_ExpectedResult()
   {
      // Arrange - I assume that you need to use the result of Sort() in the 
      // method that you're testing, so the Setup method causes sortingMock 
      // to return the specified list when Sort() is called
      ISort sortingMock = new Mock<ISort>();
      sortingMock.Setup(e => e.Sort().Returns(new int[] { 2, 5, 6, 9 }));
      MyClass myClass = new MyClass(sortingMock.Object);

      // Act 
      myClass.DoSomethingThatRequiresSorting(new int[] { 5, 9, 2, 6 });

      // Assert - check that the Sort() method was called
      myClass.Verify(e => e.Sort(It.IsAny<int[]>));
   }
}
相关问题