gpt4 book ai didi

c# - 问题单元测试 EF 和 ASP.NET 身份 - NotSupportedException : Model Compatibility

转载 作者:行者123 更新时间:2023-11-30 20:35:20 26 4
gpt4 key购买 nike

背景:

根据我的新雇主严格的单元测试要求,我正在努力获得一些单元测试经验,但单元测试作为一个整体对我来说是新的。由于对

的依赖,我在尝试测试任何使用 ASP.NET Identity 的方法时遇到了很多问题

HttpContext.Current.GetOwinContext().Authentication

HttpContext.Current.GetOwinContext().GetUserManager

现在,这个当前项目到目前为止还没有完全利用接口(interface)和依赖注入(inject),但是作为将我们组织的 Active Directory 系统合并到我们的身份数据库中的一部分(在用户登录时在用户表中创建一行使用有效的 Active Directory 凭据,然后从那时起为它们使用身份数据库),我一直致力于使用 Interfaces 和 Ninject 改造我们的身份方面,并将 FakeItEasy 添加到我们的测试单元测试项目中。

这确实意味着我们目前正在生成使用实际数据库本身的测试,而不是伪造的东西。我们知道这是一种不好的做法,这样做只是为了在我们处理第一个真正的项目时不让我们新手的头脑重载。我们已经解决了(大部分/所有)由此导致的问题,并且我们的测试在完成后进行了清理。

问题:
我在尝试对以下方法进行单元测试时遇到了一个特殊问题:

public bool ResetPassword(User user)
{
if (!user.EmailConfirmed) return false;

user.RequirePasswordReset = true;
string randomGeneratedPassword = GenerateRandomPassword(20); // defined at end of class
user.PasswordHash = hash.HashPassword(randomGeneratedPassword);

if (!UpdateUser(user)) return false;

string message = "We have received a request to reset your password. <br /><br />" +
"Your new password is shown below. <br /><br />" +
$"Your new password is: <br />{randomGeneratedPassword}<br /><br />" +
"This password is only valid for one login, and must be changed once it is used. <br /><br /><br /><br />" +
"Server<br />AmTrust Developer University";

SendFormattedEmail(user.Email, user.FullName, message, "Your password has been reset");
return true;
}

到目前为止我为此编写的测试(省略了测试用例)是:

public bool ResetPasswordTests(bool emailConfirmed)
{
//arrange
_user = new User()
{
Email = "ttestingly@test.com",
EmailConfirmed = emailConfirmed,
FirstName = "Test",
isActive = true,
isActiveDirectoryAccount = false,
LastName = "Testingly",
PasswordHash = _hash.HashPassword("secret1$"),
RequirePasswordReset = false,
UserName = "ttestingly"
};

string hashedPass = _user.PasswordHash;

_identityContext.Users.Add(_user);
_identityContext.SaveChanges();

//Suppress the email sending bit!
A.CallTo(() => _userBusinessLogic_Testable.SendFormattedEmail(null, null, null, null, null))
.WithAnyArguments()
.DoesNothing();

//act
bool result = _userBusinessLogic_Testable.ResetPassword(_user);

//assert
Assert.That(result);
Assert.That(_user.PasswordHash != hashedPass);
Assert.That(_user.RequirePasswordReset);
return result;
}

运行此测试(针对其所有各种测试用例)返回以下异常:

System.NotSupportedException: Model compatibility cannot be checked because the database does not contain model metadata. Model compatibility can only be checked for databases created using Code First or Code First Migrations.

这是由 _identityContext.Users.Add(_user); 引起的

我所看到的有关此问题的所有信息都表明它是由于在运行代码尝试连接到该数据库时打开了与数据库的连接引起的,我认为不是这种情况,或者试图让 EF 管理一个预先存在的数据库(事实并非如此:我在测试之间多次删除了我的数据库以尝试验证这一点)。

注意:目前我们团队的所有数据库都只是本地主机数据库,因此没有其他人会弄乱我的东西。

我已经看到了一个解决方案是更改连接字符串的示例,但是这个问题只发生在单元测试中 - 我已经验证在运行时,应用程序上的所有内容都在我进行任何更改之前按预期工作合并接口(interface)、Ninject 和 Active Directory - 所以我不认为连接字符串本身是问题,但这是相关的连接字符串
(它们是正确的 XML,但我不确定如何让它们到在 Stack Overflow 上正确显示,所以我删除了所有大括号):

connectionStrings
add name="ADUUserDB" providerName="System.Data.SqlClient" connectionString="Data Source=localhost\sql2014;Initial Catalog=ADUUserDB;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False; MultipleActiveResultSets=True"
/connectionStrings

最佳答案

我没有关于数据库内容的信息,但我想我对 A.CallTo 有一个想法。 FakeItEasy 不高兴被要求配置 Single,这是一种扩展方法。你应该只是配置假的。也许

A.CallTo(() => _userBusinessLogic.GetUsers(null, null, null, null, null, null, null))
.WithAnyArguments()
.Returns(new [] { _user });

公平地说,FakeItEasy 可以更好地指出您的问题(尽管通常当 A.CallTo 中只有一个方法调用时会出现这种情况,因此更容易告诉)。我创建了 issue 786跟踪这个。

关于c# - 问题单元测试 EF 和 ASP.NET 身份 - NotSupportedException : Model Compatibility,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38152748/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com