我有以下测试和相应的类,但我不知道如何验证对依赖项的调用。
根据 Moq 的测试输出,执行的调用如下:
我看到有很多关于Moq中匿名参数的问题(例如这个和这个和这个),但找不到任何与使用匿名类型作为实际类型参数相关的内容。
在Verify行中可以放什么来验证调用内部?
注意:我的示例IDependency不返回值(已经足够复杂了),但回答中涉及到Setup()和Verify()将获得额外的赞誉。
更新 Jesse的解决方案之所以通过测试,是因为我在创建示例时做出了错误选择。我应该意识到任何IGrouping<out TKey, out TElement>也是一个IEnumerable<TElement>。是否有更通用的解决方案?
更新2 我觉得我的原始示例可能过于繁琐,没有很好地表达我的问题标题。是否有任何解决方案适用于这个更简单明了的示例?
[TestFixture]
public class AnonymousGenericTypeParameterTests
{
[Test]
public void Test()
{
// Arrange
var dependency = new Mock<IDependency>();
var towns = new List<Town>
{
new Town { Name = "Lifford", County = "Donegal", Country="Ireland", Population = 1658 },
new Town { Name = "Ballyshannon", County = "Donegal", Country="Ireland", Population = 2504 },
new Town { Name = "Buxton", County = "Derbyshire", Country="United Kingdom", Population = 13599 },
};
var sut = new MyClass(dependency.Object);
// Act
sut.DoSomething(towns);
// Assert
// The following line needs to be fixed.
dependency.Verify(d => d.Execute(It.IsAny<IEnumerable<object>>(), It.IsAny<Func<object, decimal?>>()));
}
}
public interface IDependency
{
void Execute<T>(IEnumerable<T> collection, Func<T, decimal?> rateSelector);
}
public class MyClass
{
private readonly IDependency dependency;
public MyClass(IDependency dependency)
{
this.dependency = dependency;
}
public void DoSomething(IEnumerable<Town> towns)
{
var counties = towns.GroupBy(t => new {t.Country,t.County});
foreach (var county in counties)
{
dependency.Execute(county, c => c.Population);
}
}
}
public class Town
{
public string Name { get; set; }
public string County { get; set; }
public int Population { get; set; }
public string Country { get; set; }
}
根据 Moq 的测试输出,执行的调用如下:
Dependency.Execute(System.Linq.Lookup`2+Grouping[<>f__AnonymousType0`2[System.String,System.String],UniFocus.Staffscope4.Tests.Town], System.Func`2[UniFocus.Staffscope4.Tests.Town,System.Nullable`1[System.Decimal]])
我看到有很多关于Moq中匿名参数的问题(例如这个和这个和这个),但找不到任何与使用匿名类型作为实际类型参数相关的内容。
在Verify行中可以放什么来验证调用内部?
注意:我的示例IDependency不返回值(已经足够复杂了),但回答中涉及到Setup()和Verify()将获得额外的赞誉。
更新 Jesse的解决方案之所以通过测试,是因为我在创建示例时做出了错误选择。我应该意识到任何IGrouping<out TKey, out TElement>也是一个IEnumerable<TElement>。是否有更通用的解决方案?
更新2 我觉得我的原始示例可能过于繁琐,没有很好地表达我的问题标题。是否有任何解决方案适用于这个更简单明了的示例?
using Moq;
using NUnit.Framework;
namespace Tests
{
[TestFixture]
public class SimpleAnonymousGenericTypeParameterTests
{
[Test]
public void Test()
{
// Arrange
var dependency = new Mock<IDependency>();
var sut = new MyClass(dependency.Object);
// Act
sut.DoSomething("Donegal", "Lifford");
// Assert
// This verify works for both calls to Execute()
dependency.Verify(d => d.Execute(It.IsAny<object>()), Times.Exactly(2));
// This verify should specifically refer to only the first call to Execute()
dependency.Verify(d => d.Execute(It.IsAny</*HowToRepresentAnonymousTypeHere*/object>()), Times.Once);
}
public interface IDependency
{
void Execute<T>(T thing);
}
public class MyClass
{
private readonly IDependency dependency;
public MyClass(IDependency dependency)
{
this.dependency = dependency;
}
public void DoSomething(string county, string town)
{
dependency.Execute(new { county, town });
object someUnknownObject = "";
dependency.Execute(someUnknownObject);
}
}
}
}
new { prop = new { nested = 7 } }
,这个方法可能会失败。 此外,它似乎只检查了预期的属性...所以如果你的实际对象有额外的属性,它就不会失败? 我真的很喜欢这个方向,但需要填补一些漏洞,才能让它完全发挥作用。 - Lee Tickett