如何正确测试 EntityFramework、存储库模式和复杂对象的业务逻辑?
我有一个设计有些复杂的数据库,因此问题也很复杂。
我通过实体框架与该数据库进行通信。我的代码库如下所示:
- 数据层:实体框架、DbContext、数据模型。
- 存储库层:模型的基本 CRUD 操作提供者。
- 逻辑层:业务逻辑。
- Web API 层:与服务通信的控制器。
- 测试层:进行业务逻辑单元测试。
我正在编写单元测试,但我不知道如何正确编写它们,或者我的业务逻辑层是否很糟糕......在大学时,他们认为我这样做,但我想我可能会这样做误解了这种模式背后的原理...
在我的业务逻辑方法中,我传递一个域对象作为参数,然后使用 LINQ 来“查询”数据库以查找所需的结果。每个方法都使用“查询”作为逻辑。所以它很大程度上依赖于查询。 例如,我需要确定 2 个用户是否相互匹配(就像在 Tinder 中一样)
public bool AreTheyMatched(Profile requestor, Profile requested)
{
var areTheyMatched = ChatRepository.GetAll().Where(x =>
x.Profiles.Contains(requestor) &&
x.Profiles.Contains(requested) &&
x.SYS_ChatType.Type.ToLower() == "match" &&
x.Profiles.Count() == 2).Count() == 1;
return areTheyMatched;
这里的最佳实践是什么?
- 我觉得模拟查询在这里毫无用处...
- 也感觉查询不应该成为逻辑的一部分...
- 模拟 GetAll() 方法是可以的,但是由于实体框架生成的 POCO 类是自引用的(Chat 有配置文件列表、配置文件有聊天实体等等...)模拟的设置会很困难,但可能...
- 我应该从参数范围收集数据吗?
- 我如何测试查询以确定它们是否正确?
- 我怎样才能测试业务逻辑?
我在插入数据库时进行了验证简单对象的单元测试。这对我来说是理所当然的。但这个话题的复杂性似乎超出了我目前的理解范围。
I have a database with a somewhat complex design, and therefore the issue is complex too.
I communicate with this database through Entity Framework. My codebase looks like this:
- Data layer: Entity Framework, DbContext, Data models.
- Repository layer: Basic CRUD operation providers for the models.
- Logic layer: Business logic.
- Web API layer: Controllers to communicate with the service.
- Test layer: Do Business logic unit tests.
I am in the process to write unit tests and I don't know how to write them properly, or if my business logic layer is just bad... In college, they thought me to do it this way, but I think I might misunderstood the principle behind this pattern...
In my business logic method, I pass a domain object as a parameter, and I use LINQ to 'query' the database to find the needed result. Every method uses the 'queries' as logic. So it's heavily dependent on the query.
For example, I need to determine if 2 users are matched with each other or not (like in Tinder)
public bool AreTheyMatched(Profile requestor, Profile requested)
{
var areTheyMatched = ChatRepository.GetAll().Where(x =>
x.Profiles.Contains(requestor) &&
x.Profiles.Contains(requested) &&
x.SYS_ChatType.Type.ToLower() == "match" &&
x.Profiles.Count() == 2).Count() == 1;
return areTheyMatched;
What's considered the best practice here?
- I feel like mocking the query is useless here...
- Also feel like the query should not be part of the logic...
- Mocking the GetAll() method is alright, but since Entity framework generated POCO classes are self-referencing (Chat has Profile list, Profile has Chat entity, and so on...) the set up of mocking would be hard, but possible...
- Should I gather data from the scope of the parameters?
- How can I test the queries to see if they are right at all?
- How can I test business logic at all?
I did the unit tests of validating simple objects while being inserted into the database. That's a no-brainer for me. But this topic's complexity seems to be out of the scope of my current understanding.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
创建具有适合您当前测试用例的嵌套配置文件的聊天对象列表。例如,实际上包含两个配置文件的匹配的列表。然后模拟存储库以返回此列表并断言找到了匹配项。对于另一个测试用例,设置没有匹配项的聊天列表,并断言未找到匹配项。
Create a list of chat objects with nested profiles that suits your current test case. For example, a list that actually contains a match of the two profiles. Then mock the repository to return this list and assert that a match was found. For another test case, setup the chat list without a match, and assert that no match was found.