2014-11-24 25 views
3

當我需要測試一個具有很多依賴關係的類時,我使用FakeItEasy的AutoFixture,但我只是模擬其中的一些。我更喜歡使用FakeItEasy的Strict()選項嘲笑其他所有依賴項。爲了使我的測試更加乾淨,我只想嘲笑我想要的依賴關係,並能夠指定所有不模擬的依賴關係都使用Strict()創建。如何將未明確定義的依賴項註冊爲嚴格使用FakeItEasy使用AutoFixture?

在下面的例子中,我希望能夠刪除創建IDependency2模擬的兩行代碼,但保持相同的行爲:如果被測試的類訪問任何IDependency2方法,則會引發異常。

任何想法如何做到這一點?

[TestFixture] 
public class AutoTests 
{ 
    [Test] 
    public void Test() 
    { 
     // Arrange 
     IFixture fixture = new Fixture().Customize(new AutoFakeItEasyCustomization()); 

     var dependency1 = fixture.Freeze<IDependency1>(); 
     A.CallTo(() => dependency1.DoSomething()).Returns(12); 

     // I do not want to specify these two lines 
     var dependency2 = A.Fake<IDependency2>(s=>s.Strict()); 
     fixture.Register(() => dependency2); 

     // Act 
     var classUnderTest = fixture.Create<ClassUnderTest>(); 
     var actualResult = classUnderTest.MethodUnderTest(); 

     // Assert 
     Assert.That(actualResult,Is.GreaterThan(0)); 
    } 
} 

public class ClassUnderTest 
{ 
    private readonly IDependency1 _dependency1; 
    private readonly IDependency2 _dependency2; 

    public ClassUnderTest(IDependency1 dependency1, IDependency2 dependency2) 
    { 
     _dependency1 = dependency1; 
     _dependency2 = dependency2; 
    } 

    public int MethodUnderTest() 
    { 
     return _dependency1.DoSomething() 
      + _dependency2.DoSomething(); 
    } 
} 

public interface IDependency1 
{ 
    int DoSomething(); 
} 

public interface IDependency2 
{ 
    int DoSomething(); 
} 
+3

爲什麼你要測試雙打要嚴,如果你不在乎關於他們? – 2014-11-24 13:38:05

+0

我很關心那些依賴不會被錯誤地調用。如果它們沒有被明確僞造並且被使用 - 測試應該失敗。 – 2014-11-24 14:36:50

+1

爲什麼重要的是他們不會被錯誤地調用?這些依賴性是否有副作用? – 2014-11-24 14:50:14

回答

3

作爲一個折衷的解決方案,這是很簡單的實現自定義ISpecimenBuilder將所有自動生成的假貨爲嚴格假貨。你可以看看標準的Ploeh.AutoFixture.AutoFakeItEasy.FakeItEasyRelay假貨建造者,以瞭解幕後的情況。對於嚴格的假貨來作爲修改自定義生成器如下:

public class FakeItEasyStrictRelay : ISpecimenBuilder 
    { 
     public object Create(object request, ISpecimenContext context) 
     { 
      if (context == null) 
       throw new ArgumentNullException("context"); 

      if (!this.IsSatisfiedBy(request)) 
       return new NoSpecimen(request); 

      var type = request as Type; 
      if (type == null) 
       return new NoSpecimen(request); 

      var fakeFactoryMethod = this.GetType() 
       .GetMethod("CreateStrictFake", BindingFlags.Instance | BindingFlags.NonPublic) 
       .MakeGenericMethod((Type) request); 

      var fake = fakeFactoryMethod.Invoke(this, new object[0]); 

      return fake; 
     } 

     public bool IsSatisfiedBy(object request) 
     { 
      var t = request as Type; 
      return (t != null) && ((t.IsAbstract) || (t.IsInterface)); 
     } 

     private T CreateStrictFake<T>() 
     { 
      return A.Fake<T>(s => s.Strict()); 
     } 
    } 

它可以簡單地用下面的語句註冊:

IFixture fixture = new Fixture().Customize(
       new AutoFakeItEasyCustomization(new FakeItEasyStrictRelay())); 
+0

非常感謝。這正是我正在尋找的。 – 2014-11-26 08:51:47

相關問題