To implement the expected behavior I normally will need to create some "internal" modules and clases... I don't write tests for those internal modules and clases, I try to always test through the interface of these modules. And I use mocks or doubles for everything that is passed as argument.
For example...
moduleRestaurantRSpec.describe"Get menu"dodefitem_with(attrs)ItemRecord.new(attrs)enddefstore_with(records)ItemsStore.new(records)enddefget_menu(store)Restaurant.get_menu(store)endit"returns all the stored items"dostore=store_with([item_with(name: "D1"),item_with(name: "D2")])items=get_menu(store)expect(items.count).toeq2enddescribe"returns each item"doit"with name, price and description"dostore=store_with([item_with(name: "D1",price: 110,description: "D1 desc")])item=get_menu(store).firstexpect(item.name).toeq"D1"expect(item.price).toeq110expect(item.description).toeq"D1 desc"endit"knowing when is a dish"dostore=store_with([item_with(category: "dishes")])item=get_menu(store).firstexpect(item).tobe_dishendit"knowing when is not a dish"dostore=store_with([item_with(category: "beverages")])item=get_menu(store).firstexpect(item).not_tobe_dishendit"knowing when is a beverage"dostore=store_with([item_with(category: "beverages")])item=get_menu(store).firstexpect(item).tobe_beverageendit"knowing when is not a beverage"dostore=store_with([item_with(category: "dishes")])item=get_menu(store).firstexpect(item).not_tobe_beverageendendendend
or...
moduleRestaurantRSpec.describe"Add item to order"dodeforder_with(attrs)OrderRecord.new(attrs)enddefitem_with(attrs)ItemRecord.new(attrs)enddeforder_item_with(attrs)OrderItemRecord.new(attrs)enddefitems_store_with(records)ItemsStore.new(records)enddeforder_items_store_with(records)OrderItemsStore.new(records)enddefadd_item_to_order(order_id,item_id,items_store,order_items_store)Restaurant.add_item_to_order(order_id,item_id,items_store,order_items_store)endattr_reader:order,:item,:items_storebeforedo@order=order_with(id: 1)@item=item_with(name: "D1",price: 110,description: "D1 desc")@items_store=items_store_with([item])endit"creates an order item record"doorder_items_store=order_items_store_with([])expect(order_items_store).toreceive(:create).with(order_id: order.id,item_id: item.id,quantity: 1,name: "D1",price: 110)add_item_to_order(order.id,item.id,items_store,order_items_store)endit"updates the order item record, when an item is added more than once"doorder_item=order_item_with(id: 1234,order_id: order.id,item_id: item.id,quantity: 1,price: 110)order_items_store=order_items_store_with([order_item])expect(order_items_store).toreceive(:update).with(order_item.id,quantity: 2)add_item_to_order(order.id,item.id,items_store,order_items_store)endendend
What seems to be more valuable for me?
I think what I value most is...
Fast tests, to know that the system is working after every change
Be able to make changes fast
Have a place to clearly see the expected behavior
Be able to remove code without regrets
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
How do I like to unit test?
I like to write unit tests on a "use case" level...
Normally I divide my code in modules that expose some kind of business functions like...
To implement the expected behavior I normally will need to create some "internal" modules and clases... I don't write tests for those internal modules and clases, I try to always test through the interface of these modules. And I use mocks or doubles for everything that is passed as argument.
For example...
or...
What seems to be more valuable for me?
I think what I value most is...