MoQ + SetUp via conventions
Is it possible to setup an mock object's expectations via a mode of 开发者_运维问答conventions and example?
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
}
Is there an alternative to this or does one have to modify the source to achieve this? Alternatively is there a library that can do this?
You could define a set of conventions in your AssemblyInitialize
using It.Is(..)
expressions, and use them during your test setup.
It would also be easy to define some helper methods around it. For example, you could mirror the It.IsAny<T>()
syntax with an ItExt.IsConventional<T>()
method. Here's a possible implementation:
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();
}
}
And usage:
[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
}
}
Note that convention definitions must be stored as a Func<T>
, so that the expression in available for evaluation inside the Mock<T>.Setup
call.
You can't do this with Moq and I am not aware of any library that can do it.
精彩评论