2011-07-07 77 views
1

是否可以通過約定和示例的方式設置模擬對象的期望值?MoQ +通過約定設置

I.e.

class Foo 
{ 
    public virtual int? Abc { get; set; } // <-- Convention: Ignore nullable if null 
    public virtual string Xyz { get; set; } // <-- Convention: Ignore null 
    public virtual int Dingdong { get; set; } // <-- Convention: Ignore if greater than 10 
} 

是否有這個的替代或沒有一個需要修改源實現這一目標?另外還有一個庫可以做到這一點?

回答

0

你不能用Moq做到這一點,我不知道任何可以做到這一點的圖書館。

1

您可以使用It.Is(..)表達式在您的AssemblyInitialize中定義一組約定,並在測試設置期間使用它們。

也很容易定義它周圍的一些輔助方法。例如,您可以使用ItExt.IsConventional<T>()方法來鏡像It.IsAny<T>()語法。這裏是一個可能的實現:

public static class ItExt 
{ 
    private static readonly Dictionary<Type, object> RegisteredConventions = new Dictionary<Type, object>(); 

    public static void RegisterConvention<T>(Func<T> convention) 
    { 
     RegisteredConventions.Add(typeof(T), convention); 
    } 

    public static T IsConventional<T>() 
    { 
     Func<T> conventionFunc = (Func<T>)RegisteredConventions[typeof(T)]; 
     return conventionFunc(); 
    } 
} 

與用法:

[TestClass] 
public class FooTests 
{ 
    [AssemblyInitialize] 
    public static void AssemblyInitialize(TestContext context) 
    { 
     ItExt.RegisterConvention(() => It.Is<int?>(n => n.HasValue)); 
    } 

    [TestMethod] 
    public void FooTest() 
    { 
     // Arrange 
     Mock<IFoo> fooMock = new Mock<IFoo>(); 
     fooMock.Setup(f => f.Bar(ItExt.IsConventional<int?>())) 
       .Verifiable(); 

     // Act 
     fooMock.Object.Bar(1); 

     // Assert 
     fooMock.VerifyAll(); // throws 
    } 
} 

注意該公約的定義必須被存儲爲Func<T>,從而對於Mock<T>.Setup調用內部評估中可用的表達。