_customers_table.html.erb

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Phone number</th>
      <th>Description</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @customers.each do |customer| %>
      <tr>
        <td><%= customer.name %></td>
        <td><%= customer.phone_number %></td>
        <td><%= customer.description %></td>
        <td><%= link_to customer.status.humanize, toggle_status_customer_path(customer), class: "move-to-black" %></td>
        <td><%= link_to 'Show', customer %></td>
        <td><%= link_to 'Edit', edit_customer_path(customer) %></td>
        <td><%= link_to 'Destroy', customer, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>


create_customer_spec.rb

require 'rails_helper'

describe "creating new customer", type: :feature do
  let(:customer) { customer = FactoryBot.create(:customer) }

  it 'should create new customer' do
    visit '/customers/new'
    fill_in 'Name', with: customer.name
    fill_in 'Phone number', with: customer.phone_number
    click_button 'Create Customer'
    expect(page).to have_content "#{customer.name}"
  end

  it 'should change customer status' do
    visit '/'
    click_on customer.status.humanize
    expect(customer).to have_status "move_to_white_list"
  end
end


El primer ejemplo "debería crear un nuevo cliente", pero aparece un error con el segundo "debería cambiar el estado del cliente"

Capybara::ElementNotFound:
       Unable to find link or button "Move to black list"

El elemento existe y lo puedes ver en la imagen. Realmente agradecería si alguien pudiera ayudar. ingrese la descripción de la imagen aquí

Cambié el segundo ejemplo, ahora funciona. Este es mi error, no lo expliqué bien, la tabla de la "lista negra" está en una vista diferente y cuando cambia el estado, se mueve a otra página, por lo que en realidad no es posible encuéntrelo allí.

    require 'rails_helper'

describe "creating new customer", type: :feature do
  let!(:customer) { customer = FactoryBot.create(:customer) }

  it 'should create new customer' do
    visit '/customers/new'
    fill_in 'Name', with: customer.name
    fill_in 'Phone number', with: customer.phone_number
    click_button 'Create Customer'
    expect(page).to have_content "#{customer.name}"
  end

  it 'should change customer status' do
    visit '/customers'
    click_on customer.status.humanize
    expect(page).to have_content "Customer #{customer.name} moved to black list"

    visit '/black_list'
    expect(customer.reload.status).to eq "move_to_white_list"
  end
end
0
mikgn 17 nov. 2019 a las 13:44

1 respuesta

La mejor respuesta

Tiene varios problemas aquí. En primer lugar, irá a la página antes de que se haya creado la instancia del cliente, lo que significa que no se mostrará en la página. Esto se debe a que let evalúa perezosamente; consulte https://relishapp.com/rspec/rspec-core/v/3-8/docs/helper-methods/let-and-let - y solo creará el cliente el primero tiempo que se llama al cliente en la prueba.

visit '/' # <= no customer instance exists here
click_on customer.status.humanize # <= customer instance actually created here

Puede solucionarlo utilizando la versión no evaluada de forma perezosa let! que siempre creará una instancia de cliente, o llamando a customer antes de llamar a visit

En segundo lugar, su prueba es modificar la instancia del cliente en la base de datos, pero nunca volver a cargar la instancia que tiene en la memoria (por lo que el nuevo estado nunca se verá)

expect(customer.reload).to have_status "move_to_white_list"

En tercer lugar, si está utilizando un controlador que admite un comportamiento asincrónico (cualquier controlador que no sea la prueba de rack), no hay garantía de que los efectos secundarios causados ​​por los métodos de acción (click_on, etc.) se hayan completado antes de la llamada al método. devoluciones. Eso significa que lo más probable es que se llame a su expectativa antes de que cambie el estado de las instancias del cliente. Para arreglar eso, el comparador have_status necesitaría escribirse para tener un comportamiento de reintento (como todos los comparadores proporcionados por Capybara) y para tener el comportamiento de recarga en el comparador también. Esta es una de las principales razones por las que, en general, no es una buena idea verificar los cambios en la base de datos en las pruebas del sistema / características y, en su lugar, limitarse a verificar los cambios en la interfaz de usuario.

0
Thomas Walpole 17 nov. 2019 a las 18:47