Kev*_*sen 7 c# asp.net-mvc unit-testing entity-framework mocking
我知道我可以为所有查询设置DbContext的CommandTimeout,如下所示:
public class YourContext : DbContext
{
public YourContext() : base("YourConnectionString")
{
// Get the ObjectContext related to this DbContext
var objectContext = (this as IObjectContextAdapter).ObjectContext;
// Sets the command timeout for all the commands
// to 2 min instead of the default 30 sec
objectContext.CommandTimeout = 120;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我希望保持默认的30秒,除了一个需要更长时间的方法.
我应该如何更改此单个查询?
我确实试过用:
public void doSomething(){
// The using had another reason, but in this case it also
// automatically disposes of the DbContext
using(IMyDbContext = delegateDbContext()){
((IObjectContextAdapter)usingDb).ObjectContext.CommandTimeout = 120;
... // myQuery
}
}
Run Code Online (Sandbox Code Playgroud)
一切都很完美,直到我用Mock-DbContext运行我的UnitTest(是的,我确实将我的委托设置为这个Mock-DbContext).它给了我一个InvalidCastException
:
System.InvalidCastException: Unable to cast object of type
'Castle.Proxies.FakeMyDbContextProxy' to type
'System.Data.Entity.Infrastructure.IObjectContextAdapter'.
Run Code Online (Sandbox Code Playgroud)
那是因为你依赖于一个你不应该知道的实现细节(你IMyDbContext
也实现了这个事实IObjectContextAdapter
).在单元测试中,IMyDbContext
实例实际上是由模拟框架生成的代理,并且不实现IObjectContextAdapter
.
由于CommandTimeout
这个假的没有意义DbContext
,我建议你尝试施放并设置CommandTimeout
唯一的如果演员成功:
var objectContextAdapter = usingDb as IObjectContextAdapter;
if (objectContextAdapter != null)
objectContextAdapter.ObjectContext.CommandTimeout = 120;
Run Code Online (Sandbox Code Playgroud)
这样,CommandTimeout
将在实际执行环境中设置,但不在单元测试中设置(这无关紧要,因为模拟实际上并不查询数据库)
编辑:实际上,一个更好,更清洁的选择是修改IMyDbContext
以暴露一种方式来设置CommandTimeout
:
interface IMyDbContext
{
...
int CommandTimeout { get; set; }
}
class MyDbContext : IMyDbContext
{
...
public int CommandTimeout
{
get { return ((IObjectContextAdapter)this).ObjectContext.CommandTimeout; }
set { ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
现在你可以这样做:
usingDb.CommandTimeout = 120;
Run Code Online (Sandbox Code Playgroud)
而不用担心上下文的实际类型.模拟框架只会为此属性生成一个虚拟实现.
归档时间: |
|
查看次数: |
3836 次 |
最近记录: |