我有一个控制器测试库,用于处理测试中的大量冗余代码。在内部,它需要一个通用TDataSource
参数,该参数应该是一个包含IDbSet
s 的接口,用于 EF 代码。在运行时,测试库使用 RhinoMocks 构建一个模拟 TDataSource _MockDataSource = MockRepository.GenerateMock(Of TDataSource)()
。然后我使用反射来获取接口的所有 IDbSet 属性并将模拟数据库集分配给它们。(注意:这适用于虚拟类,只是接口不起作用)。
当我尝试通过IDbSet(Of TEntity)
调用来设置其中一个属性的值时propertyInfo.SetValue(dataSource, mockDbSet, Nothing)
,它不会设置实际值。没有例外,它只是不起作用。我认为这是因为该对象dataSource
实际上并不TDataSource
像类型指定的那样,而是以Castle.Proxies.IFakeDataSourceForTestingProxyf53f1730dba4492f8cafb9c731133d32
某种方式拦截了我对SetValue
. 我怎样才能解决这个问题!
下面失败方法的完整代码:
Protected Sub InjectTestData(ParamArray data() As IEnumerable)
Dim dataSourceType As Type = GetType(TDataSource)
Dim dataSourceProperties() As PropertyInfo = dataSourceType.GetProperties(BindingFlags.Public Or BindingFlags.Instance)
'match up supplied data and required data sets
For i As Integer = LBound(data) To UBound(data) Step 1
Dim [set] As IEnumerable = data(i)
Dim setType As Type = [set].GetType()
If Not setType.IsGenericType Then
Throw New ArgumentException(String.Format("Parameter {0} of the data array was not a generic IEnumerable, could not add to any IDbSet.", i))
End If
Dim modelType As Type = setType.GetGenericArguments(0)
Dim dbSetType As Type = GetType(IDbSet(Of )).MakeGenericType({modelType})
Dim foundDbSet As Boolean
For Each [property] As PropertyInfo In dataSourceProperties
If dbSetType.IsAssignableFrom([property].PropertyType) Then
Dim fakeDbSet As Object = CreateFakeDbSet(modelType, [set])
[property].SetValue(_MockDataSource, fakeDbSet, Nothing)
foundDbSet = True
End If
Next
If Not foundDbSet Then Throw New ArgumentException(String.Format("Could not find an IDbSet(Of {0}) property on {1} to match parameter {2}", modelType.Name, dataSourceType.Name, i))
Next
'add empty lists to any data sets which are still null
For Each [property] As PropertyInfo In dataSourceProperties
If [property].GetValue(_MockDataSource, Nothing) Is Nothing Then
Dim modelType As Type = [property].PropertyType.GetGenericArguments(0)
Dim fakeDbSet As Object = CreateFakeDbSet(modelType)
[property].SetValue(_MockDataSource, fakeDbSet, Nothing)
End If
Next
End Sub