2017-03-05 28 views
3

防止我想知道爲什麼,當我凍結嘲笑類而不是嘲笑接口AutoFixture +起訂量 - 凍結嘲笑類從設置

[Fact] 
public void MethodeName() 
{ 
    var fixture = new Fixture().Customize(new AutoMoqCustomization()); 

    var webRequestMock = fixture.Freeze<Mock<MyWebRequest>>(); // freezing a class + setuping a return value 
    webRequestMock.Setup(a => a.GetData()) 
    .Returns("Foo"); 

    var myService = fixture.Create<MyService>(); 

    var actual = myService.GetData(); 

    webRequestMock.Verify(a => a.GetData(), Times.Once()); // Failed it's never called once 
    Assert.Equal("Foo", actual); // Failed, if we comment previous line, 'actual' value is always empty 
} 

public class MyService 
{ 
    private readonly MyWebRequest _request; 

    public MyService(MyWebRequest request) 
    { 
     _request = request; 
    } 

    public string GetData() 
    { 
     var data = _request.GetData(); 
     return data; 
    } 
} 

public class MyWebRequest 
{ 
    public virtual string GetData() // you can see here, the method is well virtual, and should be overridable by moq. 
    { 
     return string.Empty; 
    } 
} 

1/如果我的我的測試失敗嘗試一個模擬界面,它的工作原理。

[Fact] 
public void MethodeName() 
{ 
    var fixture = new Fixture().Customize(new AutoMoqCustomization()); 
    const string expected = "Foo"; 

    var webRequestMock = fixture.Freeze<Mock<IMyWebRequest>>(); 
    webRequestMock.Setup(a => a.GetData()) 
    .Returns("Foo"); 

    var myService = fixture.Create<MyService>(); 

    var actual = myService.GetData(); 

    webRequestMock.Verify(a => a.GetData(), Times.Once()); // Success 
    Assert.Equal(expected, actual); // Success 
} 

public class MyService 
{ 
    private readonly IMyWebRequest _request; 

    public MyService(IMyWebRequest request) 
    { 
     _request = request; 
    } 

    public string GetData() 
    { 
     var data = _request.GetData(); 
     return data; 
    } 
} 

public interface IMyWebRequest 
{ 
    string GetData(); 
} 

public class MyWebRequest : IMyWebRequest 
{ 
    public virtual string GetData() 
    { 
     return string.Empty; 
    } 
} 

2/如果我使用的,而不是凍結 '注入',它的工作原理:

[Fact] 
public void MethodeName() 
{ 
    var fixture = new Fixture().Customize(new AutoMoqCustomization()); 
    const string expected = "Foo"; 

    var webRequestMock = new Mock<MyWebRequest>(); 
    webRequestMock.Setup(a => a.GetData()).Returns("Foo"); 
    fixture.Inject(webRequestMock.Object); 

    var myService = fixture.Create<MyService>(); 

    var actual = myService.GetData(); 

    webRequestMock.Verify(a => a.GetData(), Times.Once()); // Success 
    Assert.Equal(expected, actual); // Success 
} 

public class MyService 
{ 
    private readonly MyWebRequest _request; 

    public MyService(MyWebRequest request) 
    { 
     _request = request; 
    } 

    public string GetData() 
    { 
     var data = _request.GetData(); 
     return data; 
    } 
} 

public class MyWebRequest 
{ 
    public virtual string GetData() 
    { 
     // make WebRequest 
     return string.Empty; 
    } 
} 

我autofixture版本:3.6.5.0

回答

1

MyWebRequest是一個具體的(非抽象)類,並且AutoFixture.AutoMoq不創建那些使用Moq。這是設計,因爲AutoFixture內核已經處理'正常'類的創建。

You can change this behaviour如果你願意。不過,通常情況下,我會考慮不得不這樣做的設計氣味。不過,在這種情況下很難說明問題,因爲你已經很好地將問題簡化爲最小限度的再現。但是,這個問題是如此處所示,MyService不會增加任何值。我確定這不是你真正的代碼的樣子,但是因爲我不能猜測你的真實代碼是什麼樣子的,所以我不知道是否有更好的設計是可能的。