Pergunta

Estou tentando resolver um problema há algumas semanas. Estou executando testes RSPEC para o meu aplicativo Rails e eles estão funcionando bem, exceto por um erro que eu não consigo entender.

  • Estou usando o MySQL com o mecanismo Innodb.
  • Eu arrumei config.use_transactional_fixtures = true em spec_helper.rb
  • Eu carrego meus acessórios de teste manualmente com o comando rake spec:db:fixtures:load.
  • O teste RSPEC está sendo escrito para um trabalhador de BackgroundRB e está testando que um registro pode ser atualizado seu estado (através da gema State_machine).

Aqui está o meu problema:

Eu tenho um modelo chamado Listings. O teste RSPEC chama o update_sold_items Método em um arquivo chamado listing_worker.rb. Este método chama listing.sell Para um registro específico, que define a coluna 'Estado' do registro de listagem como 'vendido'. Até agora, tudo está funcionando bem, mas quando o update_sold_items Método termina, meu teste RSPEC falha aqui:

listing = Listing.find_by_listing_id(listing_id)
listing.state.should == "sold"

expected: "sold",
     got: "current" (using ==)

Eu tenho tentado rastrear por que a mudança de estado não é persistente, mas estou praticamente perdida. Aqui está o resultado de algum código de depuração que eu coloquei no update_sold_items Método durante o teste:

pp listing.state  # => "current"

listing.sell!
listing.save!

pp listing.state  # => "sold"

listing.reload

pp listing.state  # => "current"

Não consigo entender por que salva perfeitamente bem, mas depois volta ao disco original sempre que eu ligo reload, ou Listing.find etc.

Obrigado por ler isso e, por favor, faça qualquer dúvida se eu não dei informações suficientes.

Obrigado pela sua ajuda, Nathan B

PS Não tenho problemas para criar novos registros para outras classes e testar esses registros. Parece apenas um problema quando estou atualizando registros que já existem no banco de dados.

Foi útil?

Solução

Suspeito, como Nathan, problemas de transação. Tente colocar um listing.connection.execute ("Commit") logo antes da sua primeira chamada para interromper a transação e ver o que muda. Isso irá dividir você da transação, para que quaisquer chamadas adicionais de reversão não sejam eficazes.

Além disso, ao executar um comando "commit", você pode pausar o teste com um depurador e inspecionar o banco de dados de outro cliente para ver o que está acontecendo.

A outra hipótese, se a experimentação da transação não produzir nenhum resultado, é que talvez seu modelo realmente não esteja economizando no banco de dados. Verifique seus logs de consulta. (Encontre especificamente a consulta de atualização).

Esse tipo de problema realmente fede! Boa sorte!

Outras dicas

Se você deseja investigar o que tem no banco de dados ao executar testes, pode achar isso útil ...

Eu tenho um teste RSPEC onde eu salvo @user.save e ele funciona como um charme, mas então eu queria ver se ele é realmente salvo no banco de dados.

Abri o Console do Rails para o ambiente de teste

rails c test

correu

User.all

E como o esperado não tem nada

Eu corri minha especificação que contém:

user_attr_hash    = FactoryGirl.attributes_for(:user)
@user = User.new user_attr_hash
@user.save
binding.pry

Eu pensei que interromper o teste após salvar significaria que é persistido, mas esse não é o caso. Parece que o comprometimento da conexão é demitido mais tarde (não tenho idéia de quando: ) Então, como @tim Harper sugere, você deve disparar que se compromete no Console de Pry:

pry(#<RSpec::Core::ExampleGroup::Nested_1>)> User.connection.execute("COMMIT")

Agora, se você executar user.atl em seu console do Rails, você deve vê -lo;)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top