【发布时间】:2012-04-01 22:14:21
【问题描述】:
我无法让 PEX 自动覆盖调用 Linq 扩展方法的方法,例如本例中的 Where() 和 Contains():
public class MyEntity
{
public int Id { get; set; }
}
public interface IWithQueryable
{
IQueryable<MyEntity> QueryableSet();
}
public class ConsumerOfIhaveIQueryable
{
private readonly IWithQueryable _withIQueryable;
public ConsumerOfIhaveIQueryable(IWithQueryable withIQueryable)
{
// <pex>
Contract.Requires<ArgumentNullException>(
withIQueryable != null, "withIQueryable");
// </pex>
_withIQueryable = withIQueryable;
}
public IEnumerable<MyEntity> GetEntitiesByIds(IEnumerable<int> ids)
{
Contract.Requires<ArgumentNullException>(ids != null, "ids");
// <pex>
Contract.Assert
(this._withIQueryable.QueryableSet() != (IQueryable<MyEntity>)null);
// </pex>
IEnumerable<MyEntity> entities =
_withIQueryable.QueryableSet().Where(
entity => ids.Contains(entity.Id));
if (entities.Count() != ids.Count())
{
return null;
}
return entities;
}
}
[PexClass(typeof(ConsumerOfIhaveIQueryable))]
[PexAllowedExceptionFromTypeUnderTest(typeof(InvalidOperationException))]
[PexAllowedExceptionFromTypeUnderTest(typeof(ArgumentException), AcceptExceptionSubtypes = true)]
[TestClass]
public partial class ConsumerOfIhaveIQueryableTest
{
[PexMethod]
public IEnumerable<MyEntity> GetEntitiesByIds(
[PexAssumeUnderTest]ConsumerOfIhaveIQueryable target,
int[] ids)
{
var result = target.GetEntitiesByIds(ids);
PexAssert.IsTrue(result.Count() == ids.Length);
return result;
}
}
当我在这个 PexMethod 上运行 PEX 探索时,我看到了以下问题:
- 我不断收到相同的异常,PEX 不断建议您在 // 区域中看到的 Contract.Assert 形式的相同“不变”修复: 我相信这个问题在某种程度上与 Pex 与 Linq 的关系有关,但我不确定
--- 描述 测试失败:ArgumentNullException,值不能为空。 参数名称:来源
[TestMethod]
[PexGeneratedBy(typeof(ConsumerOfIhaveIQueryableTest))]
[PexRaisedException(typeof(ArgumentNullException))]
public void GetEntitiesByIdsThrowsArgumentNullException385()
{
using (PexChooseBehavedBehavior.Setup())
{
SIWithQueryable sIWithQueryable;
ConsumerOfIhaveIQueryable consumerOfIhaveIQueryable;
IEnumerable<MyEntity> iEnumerable;
sIWithQueryable = new SIWithQueryable();
consumerOfIhaveIQueryable =
ConsumerOfIhaveIQueryableFactory.Create((IWithQueryable)sIWithQueryable);
int[] ints = new int[0];
iEnumerable = this.GetEntitiesByIds(consumerOfIhaveIQueryable, ints);
}
}
--- 异常详情
System.ArgumentNullException:值不能为空。 参数名称:source at System.Linq.IQueryable'1 System.Linq.Queryable.Where(System.Linq.IQueryable'1 source, System.Linq.Expressions.Expression'1> predicate) c:\users\moran\documents\visual studio 2010\Projects\PexTuts\PexIQueryable\PexIQueryable\ConsumerOfIhaveIQueryable.cs(29):在 System.Collections.Generic.IEnumerable'1 PexIQueryable.ConsumerOfIhaveIQueryable.GetEntitiesByIds(System.Collections.Generic. IEnumerable`1 ids) c:\users\moran\documents\visual studio 2010\Projects\PexTuts\PexIQueryable\PexIQueryable.Tests\ConsumerOfIhaveIQueryableTest.cs(34):在 System.Collections.Generic.IEnumerable'1 PexIQueryable.ConsumerOfIhaveIQueryableTest.GetEntitiesByIds(PexIQueryable.ConsumerOfIhaveIQueryable 目标, System.Int32[] ids)
- 我无法让 PEX 生成相关输入。如您所见,我试图通过在我的代码中添加 PexAssert 和一个分支来“帮助”它,但是这个分支从未被覆盖,即使它应该相对简单地生成一个代码走那条路。 PEX 仅尝试将 null 或空数组作为 Id 列表传递(我在某处读到 PEX 更容易使用数组 (int[]) 而不是 IEnumerable。
很想在这方面获得一些 cmets...
顺便说一句,这是我的第一个 SO 帖子,希望我没有用太多的代码和信息发送垃圾邮件。
莫兰
【问题讨论】:
-
我刚刚注意到你发布这个...我有过吗?尽管如此,这是一项有趣的调查!
标签: linq unit-testing mstest code-contracts pex