使用Moq,RhinoMocks或类似的框架,是否有一种方法可以配置一个模拟来实现对象的所有属性的get和set,即使接口没有?
我当然可以手动模拟对象,但更喜欢使用像Moq或RhinoMocks这样的隔离框架来避免创建一堆样板类。
以下是一些示例代码:
//interface to be mocked
public interface IMyObject
{
string Property1 { set; }
}
//test method code
var mock = Moq.Mock<IMyObject>();
//...some code here to configure all properties on mock to have a get and set...
var mockObject = mock.Object;
ClassUnderTest obj = new ClassUnderTest(mockObject);
obj.MethodUnderTest();
Assert.IsTrue(!String.IsNullOrEmpty(mockObject.Property1));
按原样运行代码会在mockObject.Property1上抛出异常,因为IMyObject.Property1属性缺少get访问器。
谢谢,DanO
答案 0 :(得分:4)
public class Test
{
public void AssertOneElement()
{
var mock = new Mock<IMyObject>();
var list = default(IList<int>);
mock.SetupSet(x => x.Property1 = It.IsAny<IList<int>>())
.Callback<IList<int>>(value => list = value);
// Fails
mock.Object.Property1 = new List<int>();
// Succeeds
// mock.Object.Property1 = new List<int>(new[] { 1 });
Debug.Assert(list != null);
Debug.Assert(list.Count == 1, "Called with a list that did not contain a single element!");
}
}
public interface IMyObject
{
IList<int> Property1 { set; }
}
答案 1 :(得分:1)
使用Rhino Mocks,您可以为该属性设置期望值。这基本上表明您希望将属性设置为某个值。使用您的示例,示例测试方法体将是:
var mock = MockRepository.GenerateMock(); mock.Expect(x =&gt; x.Property1 =“Test”);
var classUnderTest = new ClassUnderTest(mock);
classUnderTest.MethodUnderTest();
mock.VerifyAllExpectations();
这会检查Property1
是否在调用mock.Expect
和调用mock.MethodUnderTest
之间的某个时间点设置为“测试”(技术上,Property1
可以在ClassUnderTest
)的构造函数中设置。
为了测试该属性是否已设置并忽略它实际设置的内容,只需将IgnoreArguments
链接到Expect
调用的返回,如下所示:
mock.Expect(x =&gt; x.Property1 =“Test1”)。IgnoreArguments();
测试更复杂的只写属性的一种方法是使用GetArgumentsForCallsMadeOn
方法。这允许您检索传递给属性的每个“调用”的参数列表。执行此操作的代码如下所示:
var mock = MockRepository.GenerateMock();
var classUnderTest = new ClassUnderTest(mock);
classUnderTest.MethodUnderTest();
//the argument in the Action is ignored, so just use null
//Property1 is of type List<string>
var arguments = mock.GetArgumentsForCallsMadeOn(x => x.Property1 = null);
//arguments[0] contains the list of arguments for the first "call" of the
//property the first index (0) of that would contain the first argument
var firstCallArguments = arguments[0];
var firstArgument = (List<string>)firstCallArguments[0];
Assert.AreEqual(3, firstArgument.Count);
我确信Moq具有类似的功能,如果你想使用它,而不是。
答案 2 :(得分:1)
使用Moq,这有效:
var mock = new Mock<IMyObject>();
// test code goes here
// Note single equals sign, not double equals
mock.VerifySet(x => x.Property1 = "expected");
SetupAllProperties不起作用。
答案 3 :(得分:1)
列表:
var mock = new Mock<IMyObject>();
// your test code
mock.VerifySet(x => x.Property1 = It.Is<IList<int>>(l => l != null && l.Count > 0));