实体框架 TDD,如何对所需字段进行单元测试模型
我开始使用 Entity Framework 4.1 对以下类使用 TDD:
public class Agent
{
// Primary key
public int ID { get; set; }
[Required]
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string Phone1 { get; set; }
}
我的断言将失败:
/// <summary>
///A test for Agent Constructor need have name
///</summary>
[TestMethod()]
public void AgentConstructorTest()
{
Agent target = new Agent();
Assert.IsNull(target);
}
当我查看生成的目标对象时,它是使用 ID = 0 创建的。我如何测试 Name
是那么需要吗?
如果 Name
字段是必需的,我如何仍然创建 Agent
对象?真实ID什么时候分配?要测试模型本身,我是否需要创建/模拟一个 DbContext
才能分配 ID?
I am start using TDD for the following class using Entity Framework 4.1:
public class Agent
{
// Primary key
public int ID { get; set; }
[Required]
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string Phone1 { get; set; }
}
My assertion will fail:
/// <summary>
///A test for Agent Constructor need have name
///</summary>
[TestMethod()]
public void AgentConstructorTest()
{
Agent target = new Agent();
Assert.IsNull(target);
}
When I look at the generated target object, it is created with ID = 0. How could I test that Name
is required then?
And if the Name
field is required, how could I still create an Agent
object? When will the real ID been assigned? To test model itself, do I need create/mockup a DbContext
to be able to assigned a ID?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
请记住,您在这里只是处理 POCO 类 - 没有什么神奇的事情会导致
Agent
类的构造失败,仅仅因为您在其属性之一上放置了自定义属性。实体框架在验证和数据映射期间检查自定义属性 - 在这种情况下,它将检查
Required
属性,并且仅在相应的字符串属性不为 null 并且它还会将 Name 映射到数据库中的不可为空列。为了反映这一点,您可以在单元测试中编写一个自定义验证例程来执行相同的检查,即确保用
Required
属性修饰的所有属性确实具有值,即类似这样的内容:这确实感觉您现在正在测试 EF,而不是您的代码。
由于 ID 是您的主键,因此仅当实体已提交到数据库时才会分配它。因此,是的,对于完整测试,您将必须模拟一个工作单元和一个为您执行此操作的上下文。不过,
IQueryable
和IEnumerable
之间存在许多陷阱,并且存在微妙(而不是那么微妙)的差异,这使得这种方法非常脆弱。就我个人而言,我建议您基于具有已知内容的单独测试数据库使用 EF 进行集成测试,并根据此测试数据库编写单元测试和预期结果 - 这可能不是真正的 TDD,但我发现这是确保唯一的方法我正在测试正确的东西。
Keep in mind that your are just dealing with POCO classes here - there is no magic going on that would allow the construction of the
Agent
class to fail just because you have put a custom attribute on one of its properties.Entity framework is checking for custom attributes during its validation and for data mapping - in this case it will check for the
Required
attribute and only declare the entity as "valid" if the corresponding string property is not null and also it will map Name to a non-nullable column in the database.To mirror that you could write a custom validation routine in your unit test that performs the same checks, i.e. makes sure that all properties that are decorated with the
Required
attribute indeed have a value, i.e something like this:This does feel like you are testing EF now though, not your code.
Since the ID is your primary key it will only be assigned when the entity has been committed to the database. So yes for full testing you will have to mock a unit of work and a context that does this for you as well. There are many pitfalls though and subtle (and not so subtle) differences between
IQueryable<T>
andIEnumerable<T>
that makes this approach very fragile.Personally I would recommend you do integration testing with EF based on a separate test database with known content and write your unit tests and expected results based on this test database - this might not be true TDD but I found it is the only way to be sure that I am testing the right thing.