简体   繁体   English

实体框架TDD,howto单元测试模型为必填字段

[英]Entity Framework TDD, howto unit-test model for required field

I am start using TDD for the following class using Entity Framework 4.1: 我开始使用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; }
    }

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? 当我查看生成的目标对象时,它是使用ID = 0创建的。我怎么能测试那个Name是否必需?

And if the Name field is required, how could I still create an Agent object? 如果需要Name字段,我怎么还能创建一个Agent对象? 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? 要测试模型本身,我是否需要创建/模拟DbContext才能分配ID?

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. 请记住,您只是在这里处理POCO类 - 没有什么可以让Agent类的构造失败只是因为您在其中一个属性上放置了自定义属性。

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. 实体框架在验证和数据映射期间检查自定义属性 - 在这种情况下,它将检查Required属性,并且如果相应的字符串属性不为null,则仅将实体声明为“有效”,并且它还将Name映射到数据库中的非可空列。

To mirror that you could write a custom validation routine in your unit test that performs the same checks, ie makes sure that all properties that are decorated with the Required attribute indeed have a value, ie something like this: 要镜像,你可以在单元测试中编写一个执行相同检查的自定义验证例程,即确保用Required属性修饰的所有属性确实都有一个值,即如下所示:

[TestMethod()]
public void AgentWithNoNameIsInvalid()
{
    Agent target = new Agent();

    Assert.IsFalse(IsValid(target));
}

This does feel like you are testing EF now though, not your code. 这确实感觉你现在正在测试EF,而不是你的代码。

Since the ID is your primary key it will only be assigned when the entity has been committed to the database. 由于ID是您的主键,因此只有在实体已提交到数据库时才会分配它。 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> and IEnumerable<T> that makes this approach very fragile. 然而, IQueryable<T>IEnumerable<T>之间存在许多陷阱和微妙(而不是那么微妙)的差异,这使得这种方法非常脆弱。

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. 就个人而言,我建议您使用基于已知内容的单独测试数据库对EF进行集成测试,并根据此测试数据库编写单元测试和预期结果 - 这可能不是真正的TDD但我发现这是确保唯一的方法我正在测试正确的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM