我有一个类似下面的类,我想进行单元测试:
public class AddUserCommand
{
IDbContext dbContext;
public AddUserCommand(IDbContext context)
{
dbContext = context;
}
public void Execute()
{
dbContext.Users.Add(new User());
dbContext.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
最后,我需要测试在使用真正的SQL数据库连接时,Execute方法是否将新用户持久保存到数据库中.但是对于我的单元测试,我显然想要使用某种模拟对象.在我的测试中,我可以创建一个模拟行为的模拟IDbContext,这一切都有效.我可以在运行Execute方法后测试模拟上下文是否包含新用户.
我的问题是,当使用模拟上下文时,如果我不调用SaveChanges方法,测试将通过.这是因为模拟上下文不需要使用sql查询来实际持久化数据.它在没有调用SaveChanges的情况下"持续存在",因为Users集合代表持久性存储.
为了检查SaveChanges是否被调用,许多在线资源(例如:http: //msdn.microsoft.com/en-us/library/ff714955.aspx和http://msdn.microsoft.com/en-gb/ data/dn314431.aspx)说要在mock环境中添加这样的东西:
public class MockDbContext : IDbContext
{
boolean saved;
public void SaveChanges {
saved = true;
}
}
Run Code Online (Sandbox Code Playgroud)
然后在调用Execute方法后测试保存的变量是否为true.但是,我发现这种方法缺少的是,如果Execute方法执行此操作,则会传递此类测试:
public void Execute()
{
dbContext.SaveChanges();
dbContext.Users.Add(new User());
}
Run Code Online (Sandbox Code Playgroud)
这当然不会保存任何更改,因为它太早完成.我相信像RhinoMocks这样的模拟框架允许你测试模拟上下文的方法调用顺序,但我也读过这不是最佳实践(你应该测试结果,而不是实现的minutae).
问题是模拟上下文并没有完全复制真正的DbContext将要做的事情.
所以我的问题是:是否有一种标准方法来模拟实体框架DbContext,以便在调用SaveChanges时,对象的任何添加或删除都只提交给模拟?或者这不是通常测试的东西?
我试图遵循我给出的大型ant构建文件,在这种情况下我无法理解xmlproperty的功能.考虑这个xml文件example.xml.
<main>
<tagList>
<tag>
<file>file1</file>
<machine>machine1</machine>
</tag>
<tag>
<file>file2</file>
<machine>machine2</machine>
</tag>
</tagList>
</main>
Run Code Online (Sandbox Code Playgroud)
在构建文件中,有一个任务可以简化为以下示例:
<xmlproperty file="example.xml" prefix="PREFIX" />
Run Code Online (Sandbox Code Playgroud)
据我所知,如果只有一个<tag>元素,我可以得到<file>with 的内容,${PREFIX.main.tagList.tag.file}
因为它大致相当于写这个:
<property name="PREFIX.main.tagList.tag.file" value="file1"/>
Run Code Online (Sandbox Code Playgroud)
但是,由于有两个<tag>,${PREFIX.main.tagList.tag.file}在这种情况下的价值是多少?如果它是某种列表,我如何迭代这两个<file>值?
我正在使用ant 1.6.2.