【问题标题】:Specification Testing with EF - The ObjectContext instance has been disposed使用 EF 进行规范测试 - ObjectContext 实例已被释放
【发布时间】:2013-08-03 13:20:47
【问题描述】:

我有以下 SpecFlow 场景:

[When(@"the registration is submitted")]
public void WhenTheRegistrationIsSubmitted()
{
    //var controller = _kernel.Get<AccountController>();

    var factory = new HockeyDbContextFactory();

    var userRepository = new Repository<User>(factory);
    var cryptoService = new CryptoService();
    var roleRepository = new Repository<Role>(factory);
    var playerService = new Mock<IPlayerService>();
    var leagueService = new Mock<ILeagueService>();
    var userService = new UserService(userRepository, cryptoService, roleRepository);
    var controller = new AccountController(userService, playerService.Object, leagueService.Object);

    controller.Register(_registerModel);
}

最终通过我的控制器调用以下方法:

public void RegisterUser(User user)
{
    var salt = _cryptoService.GenerateSalt();
    var hasedPassword = _cryptoService.HashPassword(user.Password, salt);

    user.PasswordSalt = salt;
    user.Password = hasedPassword;

    var defaultRole = _roleRepository.GetAll().Single(x => x.RoleName == "User");
    user.Roles.Add(defaultRole);

    Insert(user);
}

在我到达这一行之前,我所有的数据库调用都很好:

var defaultRole = _roleRepository.GetAll().Single(x =&gt; x.RoleName == "User");

当我在该行上设置断点并检查对 GetAll() 的调用时,我有上下文并且可以查看查询。调用 Single() 时发生异常。现在,如果我在调用 GetAll() 时加上 .Include(x =&gt; x.Users),我很好。这告诉我它与延迟加载有关。

我得到的错误是:错误:ObjectContext 实例已被释放,不能再用于需要连接的操作。

当从我的 Web 应用程序调用 RegisterUser 时,我很好。当从我的规范测试中调用 RegisterUser 时,它失败了。有没有人有煽动?

更新:

添加更多信息,这里是被调用的控制器动作:

[HttpPost]
[AllowAnonymous]
public ActionResult Register(RegisterModel model)
{
    if (!_userService.EmailIsUnique(model.EmailAddress))
        ModelState.AddModelError("EmailAddress", "Email Address is already in use.");

    if (!_userService.UserNameIsUnique(model.UserName))
        ModelState.AddModelError("UserName", "User Name is already in use");

    if (ModelState.IsValid)
    {
        // Attempt to register the user
        try
        {

            var user = Mapper.Map<User>(model);
            _userService.RegisterUser(user);
            FormsAuthentication.SetAuthCookie(model.UserName, false);

            return View("RegisterSuccess");
        }
        catch (MembershipCreateUserException e)
        {
            ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

单步执行代码,我从来没有到过FormsAuthentication.SetAuthCookie(model.UserName, false);

【问题讨论】:

  • 这意味着在您的 SpecFlow 场景中访问role.Users,在上下文消失时触发延迟加载。外人很难说这会发生在哪里。
  • 我添加了一个更新来显示控制器操作,但我的 SpecFlow 场景没有做任何其他事情。我已经删除了 DI 并尽可能地简化了问题。我确实有一个设置 _registerModel 的 Given,但这只是设置一些静态数据。

标签: c# entity-framework-5 specflow xunit


【解决方案1】:

我发现了问题所在。我正在使用此步骤播种我的测试数据库:

[BeforeFeature]
public static void BeforeFeature()
{
    MappingConfig.RegisterMappings();
    Database.SetInitializer(new TestDatabaseInitializer());
}

我的 TestDatabaseInitializer 中的上下文必须与我在我的场景中创建的上下文冲突。感谢 Gert 的评论,它给了我一个想法,让我仔细看看我的场景的其余部分发生了什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-07
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多