<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dominik Hauser</title>
    <description>The latest articles on DEV Community by Dominik Hauser (@dasdom).</description>
    <link>https://dev.to/dasdom</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F425287%2F20c28f22-0a1b-40dc-a757-0b5ccac89f8b.png</url>
      <title>DEV Community: Dominik Hauser</title>
      <link>https://dev.to/dasdom</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dasdom"/>
    <language>en</language>
    <item>
      <title>Testing a Custom UICollectionViewCompositionalLayout.list</title>
      <dc:creator>Dominik Hauser</dc:creator>
      <pubDate>Mon, 06 Jul 2020 12:56:27 +0000</pubDate>
      <link>https://dev.to/dasdom/testing-a-custom-uicollectionviewcompositionallayout-list-2d67</link>
      <guid>https://dev.to/dasdom/testing-a-custom-uicollectionviewcompositionallayout-list-2d67</guid>
      <description>&lt;p&gt;In iOS 14 Apple added a collection view compositional layout that lets us create collection views that look and behave like &lt;code&gt;UITableView&lt;/code&gt;s.&lt;br&gt;
It is based on UICollectionViewCompositionalLayout and as a result allows to create very complex collection view layouts with only little code.&lt;/p&gt;

&lt;p&gt;I believe that we should test our view controllers.&lt;br&gt;
For example I often write tests that assure that setting up a table view cell works as intended.&lt;br&gt;
An example for such a test looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;test_cellForRow_populatesCell&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// given&lt;/span&gt;
  &lt;span class="n"&gt;sut&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="c1"&gt;// when&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;indexPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;IndexPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;row&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;section&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tableView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tableView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tableView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;cellForRowAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;indexPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// then&lt;/span&gt;
  &lt;span class="kt"&gt;XCTAssertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textLabel&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sut&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;(This code is taken from my book &lt;a href="https://leanpub.com/tdd_ios_gimme_the_code"&gt;Test-Driven iOS Development - Gimme The Code&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Testing the population of a table view cell is quite easy.&lt;br&gt;
We setup the data source, get the cell from it and assert that the relevant data is set to the label in the cell.&lt;/p&gt;

&lt;p&gt;The list layout in &lt;code&gt;UICollectionViewCompositionalLayout&lt;/code&gt; works quite differently.&lt;br&gt;
I don't want to go into detail in this post how you can setup a collection view with the new list layout.&lt;br&gt;
Let's safe that for a later post.&lt;br&gt;
All you need to know is that you setup a &lt;code&gt;UICellConfigurationState&lt;/code&gt; and tell the cell that it needs to update it's configuration.&lt;br&gt;
The cell then calls the method &lt;code&gt;updateConfiguration(using:)&lt;/code&gt; and you override that method to setup the cell.&lt;/p&gt;

&lt;p&gt;You can see how this works in &lt;code&gt;CustomCellListViewController.swift&lt;/code&gt; in the sample code provided by Apple &lt;a href="https://developer.apple.com/documentation/uikit/views_and_controls/collection_views/implementing_modern_collection_views"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When I tried to write a test for this, I ran into the problem that &lt;code&gt;updateConfiguration(using:)&lt;/code&gt; is called after my test is finished.&lt;br&gt;
&lt;del&gt;So it looks like to me that UIKit postpones the call onto the next run loop.&lt;br&gt;
This means to be able to test the population of the collection view cell, I needed move the assertion to the next run loop as well.&lt;/del&gt;&lt;br&gt;
The Apple engineer &lt;a href="https://twitter.com/_mochs"&gt;@_mochs&lt;/a&gt; answered to my posts, that it should be sufficient to call &lt;code&gt;layoutIfNeeded&lt;/code&gt; on the cell to trigger populating the cell.&lt;/p&gt;

&lt;p&gt;So, this works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;test_cellForItem_returnsConfiguresCell&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;music&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Bar"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sut&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;sut&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadViewIfNeeded&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;indexPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;IndexPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;section&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collectionView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collectionView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;collectionView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;cellForItemAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;indexPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as!&lt;/span&gt; &lt;span class="kt"&gt;CustomListCell&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;listContentConfiguration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cell&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;listContentView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;configuration&lt;/span&gt; &lt;span class="k"&gt;as!&lt;/span&gt; &lt;span class="kt"&gt;UIListContentConfiguration&lt;/span&gt;
    &lt;span class="kt"&gt;XCTAssertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;listContentConfiguration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;By the way, this is a test for the sample code provided by Apple.&lt;br&gt;
I've added tests to better understand what's going on.&lt;/p&gt;

&lt;p&gt;Do you know a better way to test this?&lt;br&gt;
How would you test that the collection view cell in the list layout is populated properly?&lt;/p&gt;

&lt;p&gt;If you have questions or remarks about this post, please let me know on Twitter: &lt;a href="https://twitter.com/dasdom"&gt;@dasdom&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;(First published on &lt;a href="https://dasdom.github.io/testing-uicollection_uicollection_view_compositional_layout_list/"&gt;dasdom.github.io&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>ios</category>
      <category>testing</category>
      <category>swift</category>
    </item>
  </channel>
</rss>
