Тестирование спецификации с помощью EF — экземпляр ObjectContext удален

У меня есть следующий сценарий 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 => x.RoleName == "User");

Когда я делаю точку останова в этой строке и проверяю вызов GetAll(), у меня есть контекст, и я могу просмотреть запрос. Исключение возникает при вызове Single(). Теперь, если я добавлю .Include(x => x.Users) к вызову GetAll(), все в порядке. Это говорит мне, что это как-то связано с ленивой загрузкой.

Я получаю следующее сообщение об ошибке: ошибка: экземпляр ObjectContext удален и больше не может использоваться для операций, требующих подключения.

Когда 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);


person ryanw51    schedule 03.08.2013    source источник
comment
Это означает, что в вашем сценарии SpecFlow осуществляется доступ к role.Users, вызывая ленивую загрузку, пока контекст отсутствует. Трудно сказать постороннему, где это могло произойти.   -  person Gert Arnold    schedule 03.08.2013
comment
Я добавил обновление, чтобы показать действие контроллера, но мой сценарий SpecFlow больше ничего не делает. Я вырезал DI и максимально упростил задачу. У меня есть Given, который устанавливает _registerModel, но это просто установка некоторых статических данных.   -  person ryanw51    schedule 04.08.2013


Ответы (1)


Я понял, в чем дело. Я заполнил свою тестовую базу данных следующим шагом:

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

Контекст в моем TestDatabaseInitializer должен был конфликтовать с контекстом, который я создал в своем сценарии. Спасибо за комментарий, Герт, он дал мне идею поближе взглянуть на то, что происходит в остальной части моего сценария.

person ryanw51    schedule 03.08.2013