Skip to content

Integration Test: Database Layer

Fabian Schmengler edited this page Oct 9, 2017 · 7 revisions

You will learn

  • writing tests for the database layer
  • writing testable abstractions
  • creating custom fixtures

Exercise 1: Custom Repository

For this exercise we continue working on the contacts module from the [[Controllers Exercises|Integration Test: Controllers]]. If you did not complete that, you can also start with the module skeleton by cloning https://github.com/tddwizard/magento2-exercise-contact.git into app/code/TddWizard/ExerciseContact.

The generated code from Mage2Gen already contains a repository for the Inquiry model and we don't usually want to write tests for generated code. In this case, the generated code had some issues and I already wrote a basic test for the repository while fixing these. The fixture for this test is just one inquiry model, created in setUp() and deleted in tearDown().

For further development, the module will need a new method in the repository, getByEmail($email), which returns an array of inquiries with the given email address.

Add a test to InquiryRepositoryTest, then implement getByEmail() as described.

When you are done, compare the test with the existing testGetList() test, which also tests filtering inquiries by email. Which one is simpler? What does this mean for production code?

Check out solution-integration-test-6 to see a solution.

Exercise 2: Product Attributes

Clone https://github.com/tddwizard/magento2-exercise-brands.git into app/code/TddWizard/ExerciseBrands. It contains a module skeleton with generated code that adds a product attribute, brand, and will create a block that shows products filtered by brand.

First, write a test to verify that the new product attribute has been added correctly (Use Magento\Catalog\Api\ProductAttributeRepositoryInterface to look for the attribute).

For the block, we need a way to filter products. It is not recommended to use product collections directly, but use the service contracts, i.e. the repositories. With getList() it's possible to filter by attribute. But remember from the last exercise that it's relatively complex. If we follow the Magento conventions to never instantiate anything with new, it gets even more complex. So let's write a shortcut, our own product repository.

Write a class ProductBrandRepository with a method getProductsByBrand($brand). To test it, we will need a fixture with some products that have the brand attribute set. Unfortunately that means we cannot simply reuse the core fixtures like before, we need to write our own!

You have two options:

You may want to try both approaches and compare.

Do not forget to use the @magentoDbIsolation enabled annotation

Check out solution-integration-test-1 to see a solution.

Exercise 3: Layout

Now let's create the block and display it on the product page, like this:

Other products of $BRAND

You will need to create the block, layout XML and a template. Start by writing a controller test with appropiate product fixtures (unfortunately, testing the layout on a lower level is nearly impossible).

Check out solution-integration-test-2 to see a solution.

Clone this wiki locally