100 lines
No EOL
7 KiB
JSON
100 lines
No EOL
7 KiB
JSON
{
|
|
"uuid": [
|
|
{
|
|
"value": "eaab8112-8eb0-4a42-be8f-27d634b25cd5"
|
|
}
|
|
],
|
|
"langcode": [
|
|
{
|
|
"value": "en"
|
|
}
|
|
],
|
|
"type": [
|
|
{
|
|
"target_id": "daily_email",
|
|
"target_type": "node_type",
|
|
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
|
}
|
|
],
|
|
"revision_timestamp": [
|
|
{
|
|
"value": "2025-04-21T01:21:38+00:00"
|
|
}
|
|
],
|
|
"revision_uid": [
|
|
{
|
|
"target_type": "user",
|
|
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
|
}
|
|
],
|
|
"revision_log": [],
|
|
"status": [
|
|
{
|
|
"value": true
|
|
}
|
|
],
|
|
"uid": [
|
|
{
|
|
"target_type": "user",
|
|
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
|
}
|
|
],
|
|
"title": [
|
|
{
|
|
"value": "Keep logic within tests for as long as you can"
|
|
}
|
|
],
|
|
"created": [
|
|
{
|
|
"value": "2024-02-16T00:00:00+00:00"
|
|
}
|
|
],
|
|
"changed": [
|
|
{
|
|
"value": "2025-04-21T01:21:38+00:00"
|
|
}
|
|
],
|
|
"promote": [
|
|
{
|
|
"value": false
|
|
}
|
|
],
|
|
"sticky": [
|
|
{
|
|
"value": false
|
|
}
|
|
],
|
|
"default_langcode": [
|
|
{
|
|
"value": true
|
|
}
|
|
],
|
|
"revision_translation_affected": [
|
|
{
|
|
"value": true
|
|
}
|
|
],
|
|
"path": [
|
|
{
|
|
"alias": "\/daily\/2024\/02\/16\/keep-logic-within-tests-for-as-long-as-you-can",
|
|
"langcode": "en"
|
|
}
|
|
],
|
|
"body": [
|
|
{
|
|
"value": "\n <p>Inspired by some recent podcast guests, I've started writing the first code for a Drupal-based SaaS product that I've been thinking of creating.<\/p>\n\n<p>Here's an early iteration of the first test I wrote:<\/p>\n\n<pre><code class=\"language-php\">public function test_it_creates_a_project_node_from_json(): void {\n self::assertNull(Node::load(id: 1));\n\n $this->installEntitySchema(entity_type_id: 'node');\n $this->installConfig(modules: self::$modules);\n\n $projectData = json_decode(json: self::$projectJson, associative: TRUE);\n self::assertNotNull($projectData);\n\n Node::create([\n 'title' => $projectData['list'][0]['title'],\n 'type' => 'drupal_project',\n ])->save();\n\n $node = Node::load(id: 1);\n\n self::assertNotNull($node);\n self::assertInstanceOf(actual: $node, expected: NodeInterface::class);\n self::assertSame(actual: $node->label(), expected: 'Override Node Options');\n\n self::assertSame(\n actual: $node->get('field_drupalorg_node_id')->getString(),\n expected: strval(107871),\n );\n}\n<\/code><\/pre>\n\n<p>It checks that, given some defined JSON data, it will create a node in my database.<\/p>\n\n<p>It confirms no node ID exists when starting, runs some setup setups (this is a Kernel test), decodes the JSON, creates the node and asserts it contains the expected values.<\/p>\n\n<p>There are two things that you may be wondering...<\/p>\n\n<ul>\n<li>Why do you have test setup code that you'll need within the test? Won't you need that for every test?<\/li>\n<li>Why are you creating the node within the test and not somewhere else?<\/li>\n<\/ul>\n\n<p>The answer to both is that this is the first test, and I want to write <strong>as little code as possible for it to pass<\/strong>.<\/p>\n\n<p>When I write the second test, I'll either need to duplicate the setup lines or extract them to a <code>setUp()<\/code> method.<\/p>\n\n<p>I'll also need to refactor the code that creates the node.<\/p>\n\n<p>Once I've written the second test, to get it to pass, I refactored to use Repository, Builder and Action classes.<\/p>\n\n<p>If there's a regression, the test I had will fail, and I could revert to the passing version before reattempting the refactor.<\/p>\n\n<p>With test-driven development, I want to work in small and simple steps and get to green by making the smallest and easiest possible change.<\/p>\n\n<p>When I have a test that forces me to refactor and adopt a more complex approach, I'll do it.<\/p>\n\n ",
|
|
"format": "full_html",
|
|
"processed": "\n <p>Inspired by some recent podcast guests, I've started writing the first code for a Drupal-based SaaS product that I've been thinking of creating.<\/p>\n\n<p>Here's an early iteration of the first test I wrote:<\/p>\n\n<pre><code class=\"language-php\">public function test_it_creates_a_project_node_from_json(): void {\n self::assertNull(Node::load(id: 1));\n\n $this->installEntitySchema(entity_type_id: 'node');\n $this->installConfig(modules: self::$modules);\n\n $projectData = json_decode(json: self::$projectJson, associative: TRUE);\n self::assertNotNull($projectData);\n\n Node::create([\n 'title' => $projectData['list'][0]['title'],\n 'type' => 'drupal_project',\n ])->save();\n\n $node = Node::load(id: 1);\n\n self::assertNotNull($node);\n self::assertInstanceOf(actual: $node, expected: NodeInterface::class);\n self::assertSame(actual: $node->label(), expected: 'Override Node Options');\n\n self::assertSame(\n actual: $node->get('field_drupalorg_node_id')->getString(),\n expected: strval(107871),\n );\n}\n<\/code><\/pre>\n\n<p>It checks that, given some defined JSON data, it will create a node in my database.<\/p>\n\n<p>It confirms no node ID exists when starting, runs some setup setups (this is a Kernel test), decodes the JSON, creates the node and asserts it contains the expected values.<\/p>\n\n<p>There are two things that you may be wondering...<\/p>\n\n<ul>\n<li>Why do you have test setup code that you'll need within the test? Won't you need that for every test?<\/li>\n<li>Why are you creating the node within the test and not somewhere else?<\/li>\n<\/ul>\n\n<p>The answer to both is that this is the first test, and I want to write <strong>as little code as possible for it to pass<\/strong>.<\/p>\n\n<p>When I write the second test, I'll either need to duplicate the setup lines or extract them to a <code>setUp()<\/code> method.<\/p>\n\n<p>I'll also need to refactor the code that creates the node.<\/p>\n\n<p>Once I've written the second test, to get it to pass, I refactored to use Repository, Builder and Action classes.<\/p>\n\n<p>If there's a regression, the test I had will fail, and I could revert to the passing version before reattempting the refactor.<\/p>\n\n<p>With test-driven development, I want to work in small and simple steps and get to green by making the smallest and easiest possible change.<\/p>\n\n<p>When I have a test that forces me to refactor and adopt a more complex approach, I'll do it.<\/p>\n\n ",
|
|
"summary": null
|
|
}
|
|
],
|
|
"feeds_item": [
|
|
{
|
|
"imported": "2025-04-21T01:21:38+00:00",
|
|
"guid": null,
|
|
"hash": "d430f601217ebbf8a937cf42e8daac88",
|
|
"target_type": "feeds_feed",
|
|
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
|
}
|
|
]
|
|
} |