我有包含IEnumerable参数的构造函数。当我尝试将具体对象注入automocker时,它不会被使用。
当我使用包含IEnumerable属性的包装器类时,它们都按预期工作。
如何测试TestClass1?
public class TestClass1
{
public TestClass1(IEnumerable<IItem> items)
{
Items = items;
}
public IEnumerable<IItem> Items { get; private set; }
}
[TestMethod]
public void TestClass1Constructor()
{
RhinoAutoMocker<TestClass1> autoMocker = new RhinoAutoMocker<TestClass1>();
IEnumerable<IItem> items = new[] { MockRepository.GenerateMock<IItem>() };
autoMocker.Inject(items);
Assert.AreEqual(1, autoMocker.ClassUnderTest.Items.Count());
}
测试结果如下:
Assert.AreEqual失败。预期:其中-1。实际:&℃,GT;
public class TestClass2
{
public TestClass2(WrapperClass numbersWrapper)
{
Items = numbersWrapper.Items;
}
public IEnumerable<IItem> Items { get; private set; }
}
[TestMethod]
public void TestClass2Constructor()
{
RhinoAutoMocker<TestClass2> autoMocker = new RhinoAutoMocker<TestClass2>();
WrapperClass numbers = new WrapperClass(new[] { MockRepository.GenerateMock<IItem>() });
autoMocker.Inject(numbers);
Assert.AreEqual(1, autoMocker.ClassUnderTest.Items.Count());
}
测试结果如下:
成功。
答案 0 :(得分:2)
看了the source code for the AutoMocker<TTargetClass>
class后,我注意到以下内容:
IEnumerable<T>
的依赖项的处理方式不同(见下文)这是来自AutoMocker<TTargetClass>
类的一段代码,它显示了如何解析构造函数依赖项(为简洁起见,我删除了一些代码行):
private object[] getConstructorArgs()
{
ConstructorInfo ctor = Constructor.GetGreediestConstructor(typeof (TTargetClass));
var list = new List<object>();
foreach (ParameterInfo parameterInfo in ctor.GetParameters())
{
Type dependencyType = parameterInfo.ParameterType;
if (dependencyType.IsArray)
{
[...]
}
else if (dependencyType.Closes(typeof (IEnumerable<>)))
{
Type @interface = dependencyType.FindFirstInterfaceThatCloses(typeof (IEnumerable<>));
Type elementType = @interface.GetGenericArguments().First();
// Here's the interesting code:
var builder = typeof (EnumerableBuilder<>).CloseAndBuildAs<IEnumerableBuilder>(_container,
elementType);
list.Add(builder.ToEnumerable());
}
else
{
object dependency = _container.GetInstance(dependencyType);
list.Add(dependency);
}
}
return list.ToArray();
}
代码显示依赖关系通常使用_container.GetInstance
解决,但有两个例外:ararys和IEnumerable<>
s
对于IEnumerable<T>
,事实证明使用了_container.GetAllInstances(typeof(T))
。在您的情况下,您应该注入几个IItem
个实例,而不是IEnumerable<IItem>
。负责此操作的代码是EnumerableBuilder<T>
类,可以在the same file中找到(最后)。
好的,说得够多。我不确定我的解释是否足够清楚,所以下面是两个测试通过的代码。希望这能澄清一切:
[Test]
public void Test_OneItem()
{
var autoMocker = new RhinoAutoMocker<TestClass1>();
autoMocker.Inject(MockRepository.GenerateMock<IItem>());
Assert.AreEqual(1, autoMocker.ClassUnderTest.Items.Count());
}
[Test]
public void Test_TwoItems()
{
var autoMocker = new RhinoAutoMocker<TestClass1>();
autoMocker.Inject(MockRepository.GenerateMock<IItem>());
autoMocker.Inject(MockRepository.GenerateMock<IItem>());
Assert.AreEqual(2, autoMocker.ClassUnderTest.Items.Count());
}