问题描述
我们的编程涉及使用内存数据的一些Mock测试。因此,我们实现了以下代码,首先创建客户对象的内存数据 //让我们创建一些内存数据
//创建一个Customer
列表< Customer> listOfCustomers = new List< BlahBlahExample.Domain.Objects.Customer>()
{new Customer {CustomerID =1,Orders = new HashSet< Order>(),CustomerDemographics = new HashSet< CustomerDemographic>(),CompanyName =芝加哥公牛队,ContactName =Michael Jordan,ContactTitle =top basket ball player,Address =332 testing lane,City =Chicago,Region =Illinois,PostalCode =484894,Country = USA,Phone =3293993,Fax =39393},
new Customer {CustomerID =2,Orders = new HashSet< Order>(),CustomerDemographics = new HashSet< CustomerDemographic>() CompanyName =迈阿密热火,ContactName =Lebron James,ContactTitle =第二好篮球选手,地址=90 test street,City =Miami,Region =Florida,PostalCode =4869394 Country =USA,Phone =3293213,Fax =33393},
new Customer {CustomerI D =3,Orders = new HashSet< Order>(),CustomerDemographics = new HashSet< CustomerDemographic>(),CompanyName =Oklahoma City Thunder,ContactName =Kevin Durant,ContactTitle =当前顶级篮球球员 ,Address =35 test row,City =Oklahoma City,Region =Oklahoma,PostalCode =480290,Country =USA,Phone =304923,Fax =33325}
};
//将列表转换为IQueryable列表
IQueryable< Customer> queryableListOfCustomerInMemoryData = listOfCustomers.AsQueryable();
//让我们创建一个Mocked DbSet对象。
Mock< DbSet< BlahBlahExample.Domain.Objects.Customer>> mockDbSet = new Mock< DbSet< BlahBlahExample.Domain.Objects.Customer>>();
//强制DbSet返回我们转换的列表对象的IQueryable成员
//作为
//数据源
mockDbSet.As< IQueryable&BlanBlahExample。 Domain.Objects.Customer>>()。Setup(m => m.Provider).Returns(queryableListOfCustomerInMemoryData.Provider);
mockDbSet.As< IQueryable< BlahBlahExample.Domain.Objects.Customer>>()。Setup(m => m.Expression).Returns(queryableListOfCustomerInMemoryData.Expression);
mockDbSet.As< IQueryable< BlahBlahExample.Domain.Objects.Customer>>()。Setup(m => m.ElementType).Returns(queryableListOfCustomerInMemoryData.ElementType);
mockDbSet.As< IQueryable< BlahBlahExample.Domain.Objects.Customer>>()。Setup(m => m.GetEnumerator())返回(queryableListOfCustomerInMemoryData.GetEnumerator());
mockDbSet.Setup(m => m.Add(It.IsAny< Customer>()))。回调< Customer>(listOfCustomers.Add);
Mock< BlahBlahAuditMappingProvider> jsAudtMppngPrvdr = new Mock< BlahBlahAuditMappingProvider>();
Mock< BlahBlahDataContext> fctry = new Mock< BlahBlahDataContext>(jsAudtMppngPrvdr.Object);
Mock< BlahBlahDataContext> qryCtxt = new Mock< BlahBlahDataContext>();
Mock< BlahBlahAuditContext> audtCtxt = new Mock< BlahBlahAuditContext>();
Mock< BlahBlahDataContext> mockedReptryCtxt = new Mock< BlahBlahDataContext>();
mockedReptryCtxt.Setup(q => q.Customers).Returns(mockDbSet.Object);
mockedReptryCtxt.Setup(q => q.Set< Customer>())。Returns(mockDbSet.Object);
mockedReptryCtxt.CallBase = true;
DbSet< Customer> inMemoryDbSetCustomer = mockedReptryCtxt.Object.Set< Customer>();
在下面的代码摘录(这是我们的Test In Test)中,我添加了一个新的客户到现有的内存数据,然后在Mocked对象上调用SaveChanges。
Customer returnCust =(Customer)(mockedReptryCtxt ()CustomerList = new HashSet< Order>(),CustomerDemographics = new HashSet< CustomerDemographic>(),CompanyName =Kolkota Knights,ContactName = Sachin Tendulkar,ContactTitle =当前顶级板球运动员,Address =35 test row,City =Kolkota,Region =West Bengal,PostalCode =3454534,Country =India,Phone = 304923,Fax =33325}));
mockedReptryCtxt.Object.SaveChanges();
稍后在代码中,我有以下摘录的代码,其中_context.Set()将返回我们之前创建的In-Memory Data DBSet
var query = _context.Set< TEntity>()。AsQueryable();
if(typeof(TEntity).Name.Contains(Audit))
{
return query;
}
if(includes!= null&& includes.Any())
{
foreach(var include in includes)
{
query = query.Include(include);
}
}
列表< TEntity> resultsAsList = query.ToList(); //错误Thrown当使用ToList()
var results = resultsAsList.AsQueryable();
当我们调用ToList()时,它会抛出以下错误:
System.InvalidOperationException被用户代码未处理
HResult = -2146233079
Message =集合被修改;枚举操作可能无法执行。
Source = mscorlib
StackTrace:
在System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource资源)
在System.Collections.Generic.List`1.Enumerator.MoveNextRare()
在System.Collections.Generic.List`1.Enumerator.MoveNext()
在System.Collections.Generic.List`1..ctor(IEnumerable`1集合)
在System.Linq.Enumerable .dList [TSource](IEnumerable`1 source)
在BlahBlah.Framework.EntityFramework.EntityFrameworkRepository`1.ConcreteQuery(List`1 includes)在d:\EMIS\BlahBlah Framework\BlahBlahFrameworkLightweight\BlahBlah中。 Framework.EntityFramework\EntityFrameworkRepository.cs:line 51
在Castle.Proxies.EntityFrameworkRepository`1Proxy.ConcreteQuery_callback(List`1 includes)
在Castle.Proxies.Invocations.EntityFrameworkRepository`1_ConcreteQuery.InvokeMethodOnTarget()
在Castle.DynamicProxy.AbstractInvocation.Proceed()
在Moq.Proxy.CastleProxyFactory.CallContext.InvokeBase()
在Moq.InvokeBase.HandleIntercept(ICallContext调用,InterceptorContext ctx,CurrentInterceptContext localctx)
在Moq.Interceptor.Intercept(ICallContext调用)
在Moq.Proxy.CastleProxyFactory.Interceptor.Intercept(IInvocation调用)
在Castle.DynamicProxy.AbstractInvocation.Proceed()
在Castle.Proxies.EntityFrameworkRepository`1Proxy.ConcreteQuery(List`1包括)
在BlahBlah.Framework.Core.Repository.BaseRepository`1.Query(List`1 includes)在d:\EMIS\BlahBlah Framework\BlahBlahFrameworkLightweight\BlahBlah.Framework.Core\Repository\BaseRepository.cs :Castle.Proxies.EntityFrameworkRepository`1Proxy.Query_callback(List`1 includes)$ 149
在Castle.Proxies.Invocations.IRepository`1_Query.InvokeMethodOnTarget()
在Castle.DynamicProxy。抽象Moq.Proxy.CastleProxyFactory.CallContext.InvokeBase()中的
Moq.InvokeBase.HandleIntercept(ICallContext调用,InterceptorContext ctx,CurrentInterceptContext localctx)
在Moq.Interceptor处的
。 Intercept(ICallContext invocation)
在Moq.Proxy.CastleProxyFactory.Interceptor.Intercept(IInvocation调用)
在Castle.DynamicProxy.AbstractInvocation.Proceed()
在Castle.Proxies.EntityFrameworkRepository`1Proxy。查询(List`1包括)
在BlahBlah.Test.Unit.CntrlrsTests.CustomerControllerTest.Test_Creation_Of_Customer_Using_Constructor_Of _Customer_Controller_That_Expects_Arguments()在d:\EMIS\BlahBlah Framework\BlahBlahFrameworkLightweight\BlahBlah.Test.Unit\CntrlrsTests\\ \\ CustomerControllerTest.cs:行278
InnerException:
我们需要采取哪些步骤命令停止说e我们发现一个非常笨拙的解决方案:
/ p>
列表< TEntity> tempList = new List< TEntity>(); (int i = query.Count() - 1; i> = 0; i--)
{
tempList.Add(query.ElementAt(i))
);
}
列表< TEntity> resultsAsList = tempList.ToList();
var results = resultsAsList.AsQueryable();
在上述代码中,使用索引的for循环遍历DBSet很重要实例。此外,在循环中,您将每个元素添加到列表。 (基本上,避免使用迭代器很重要)
Our programming involves some Mock testing using In-Memory Data. Therefore, we implemented the following code that would first create In-Memory Data of Customer objects
// Let us create some in-memory data
// Create a list of Customer
List<Customer> listOfCustomers = new List<BlahBlahExample.Domain.Objects.Customer>()
{ new Customer { CustomerID = "1 ",Orders = new HashSet<Order>(), CustomerDemographics = new HashSet<CustomerDemographic>(), CompanyName = "Chicago Bulls", ContactName = "Michael Jordan", ContactTitle = "top basket ball player", Address = "332 testing lane", City = "Chicago", Region = "Illinois", PostalCode = "484894", Country = "USA", Phone = "3293993", Fax = "39393" },
new Customer { CustomerID = "2 ",Orders = new HashSet<Order>(),CustomerDemographics = new HashSet<CustomerDemographic>() , CompanyName = "Miami Heat", ContactName = "Lebron James", ContactTitle = "second best basket ball player", Address = "90 test street", City = "Miami", Region = "Florida", PostalCode = "4869394", Country = "USA", Phone = "3293213", Fax = "33393" },
new Customer { CustomerID = "3 ",Orders = new HashSet<Order>(),CustomerDemographics = new HashSet<CustomerDemographic>() , CompanyName = "Oklahoma City Thunder", ContactName = "Kevin Durant", ContactTitle = "current top basket ball player", Address = "35 test row", City = "Oklahoma City", Region = "Oklahoma", PostalCode = "480290", Country = "USA", Phone = "304923", Fax = "33325" }
};
// Convert the list to an IQueryable list
IQueryable<Customer> queryableListOfCustomerInMemoryData = listOfCustomers.AsQueryable();
// Let us create a Mocked DbSet object.
Mock<DbSet<BlahBlahExample.Domain.Objects.Customer>> mockDbSet = new Mock<DbSet<BlahBlahExample.Domain.Objects.Customer>>();
// Force DbSet to return the IQueryable members
// of our converted list object as its
// data source
mockDbSet.As<IQueryable<BlahBlahExample.Domain.Objects.Customer>>().Setup(m => m.Provider).Returns(queryableListOfCustomerInMemoryData.Provider);
mockDbSet.As<IQueryable<BlahBlahExample.Domain.Objects.Customer>>().Setup(m => m.Expression).Returns(queryableListOfCustomerInMemoryData.Expression);
mockDbSet.As<IQueryable<BlahBlahExample.Domain.Objects.Customer>>().Setup(m => m.ElementType).Returns(queryableListOfCustomerInMemoryData.ElementType);
mockDbSet.As<IQueryable<BlahBlahExample.Domain.Objects.Customer>>().Setup(m => m.GetEnumerator()).Returns(queryableListOfCustomerInMemoryData.GetEnumerator());
mockDbSet.Setup(m => m.Add(It.IsAny<Customer>())).Callback<Customer>(listOfCustomers.Add);
Mock<BlahBlahAuditMappingProvider> jsAudtMppngPrvdr = new Mock<BlahBlahAuditMappingProvider>();
Mock<BlahBlahDataContext> fctry = new Mock<BlahBlahDataContext>(jsAudtMppngPrvdr.Object);
Mock<BlahBlahDataContext> qryCtxt = new Mock<BlahBlahDataContext>();
Mock<BlahBlahAuditContext> audtCtxt = new Mock<BlahBlahAuditContext>();
Mock<BlahBlahDataContext> mockedReptryCtxt = new Mock<BlahBlahDataContext>();
mockedReptryCtxt.Setup(q => q.Customers).Returns(mockDbSet.Object);
mockedReptryCtxt.Setup(q => q.Set<Customer>()).Returns(mockDbSet.Object);
mockedReptryCtxt.CallBase = true;
DbSet<Customer> inMemoryDbSetCustomer = mockedReptryCtxt.Object.Set<Customer>();
In the next excerpt of code( which is our "Code Under Test"), I add a new Customer to the existing In-Memory Data, and then Invoke SaveChanges on the Mocked Object.
Customer returnCust = (Customer)(mockedReptryCtxt.Object.Set<Customer>().Add(new Customer { CustomerID = "4 ", Orders = new HashSet<Order>(), CustomerDemographics = new HashSet<CustomerDemographic>(), CompanyName = "Kolkota Knights", ContactName = "Sachin Tendulkar", ContactTitle = "current top cricket player", Address = "35 test row", City = "Kolkota", Region = "West Bengal", PostalCode = "3454534", Country = "India", Phone = "304923", Fax = "33325" }));
mockedReptryCtxt.Object.SaveChanges();
Later on in the code, I have the following excerpt of code where _context.Set() will return the In-Memory Data DBSet that we created previously
var query = _context.Set<TEntity>().AsQueryable();
if (typeof(TEntity).Name.Contains("Audit"))
{
return query;
}
if (includes != null && includes.Any())
{
foreach (var include in includes)
{
query = query.Include(include);
}
}
List<TEntity> resultsAsList = query.ToList(); // Error Thrown When using ToList()
var results = resultsAsList.AsQueryable();
When we invoke ToList(), it Throws the following Error:
System.InvalidOperationException was unhandled by user code
HResult=-2146233079
Message=Collection was modified; enumeration operation may not execute.
Source=mscorlib
StackTrace:
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at System.Collections.Generic.List`1.Enumerator.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at BlahBlah.Framework.EntityFramework.EntityFrameworkRepository`1.ConcreteQuery(List`1 includes) in d:\EMIS\BlahBlah Framework\BlahBlahFrameworkLightweight\BlahBlah.Framework.EntityFramework\EntityFrameworkRepository.c s:line 51
at Castle.Proxies.EntityFrameworkRepository`1Proxy.ConcreteQuery_callback(List`1 includes)
at Castle.Proxies.Invocations.EntityFrameworkRepository`1_ConcreteQuery.InvokeMethodOnTarget()
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Moq.Proxy.CastleProxyFactory.CallContext.InvokeBase()
at Moq.InvokeBase.HandleIntercept(ICallContext invocation, InterceptorContext ctx, CurrentInterceptContext localctx)
at Moq.Interceptor.Intercept(ICallContext invocation)
at Moq.Proxy.CastleProxyFactory.Interceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.EntityFrameworkRepository`1Proxy.ConcreteQuery(List`1 includes)
at BlahBlah.Framework.Core.Repository.BaseRepository`1.Query(List`1 includes) in d:\EMIS\BlahBlah Framework\BlahBlahFrameworkLightweight\BlahBlah.Framework.Core\Repository\BaseRepository.cs:line 149
at Castle.Proxies.EntityFrameworkRepository`1Proxy.Query_callback(List`1 includes)
at Castle.Proxies.Invocations.IRepository`1_Query.InvokeMethodOnTarget()
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Moq.Proxy.CastleProxyFactory.CallContext.InvokeBase()
at Moq.InvokeBase.HandleIntercept(ICallContext invocation, InterceptorContext ctx, CurrentInterceptContext localctx)
at Moq.Interceptor.Intercept(ICallContext invocation)
at Moq.Proxy.CastleProxyFactory.Interceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.EntityFrameworkRepository`1Proxy.Query(List`1 includes)
at BlahBlah.Test.Unit.CntrlrsTests.CustomerControllerTest.Test_Creation_Of_Customer_Using_Constructor_Of _Customer_Controller_That_Expects_Arguments() in d:\EMIS\BlahBlah Framework\BlahBlahFrameworkLightweight\BlahBlah.Test.Unit\CntrlrsTests\CustomerControllerTest.cs:line 278
InnerException:
What steps do we need to take in order to stop the said error from being thrown( preferably without Changing too much of our Code Under Test)?
I found a really Clumsy Solution:
List<TEntity> tempList = new List<TEntity>();
for (int i = query.Count() - 1; i >= 0; i--)
{
tempList.Add(query.ElementAt(i));
}
List<TEntity> resultsAsList = tempList.ToList();
var results = resultsAsList.AsQueryable();
In the aforementioned code, it is important to use a for loop with an index to go through the DBSet instance. Furthermore, in the loop, you add each element to a List. ( Basically, it's important to Avoid using the Iterator)
这篇关于系统修改了哪些步骤?枚举操作可能无法执行。错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!