Basic TDD: Red-Green-Refactor Pattern

About Red-Green-Refactor

The Red stage

The Green stage

Refactor

Example: An Article Model

  1. An empty constructor for the struct
  2. It stores values related to a post/article, like the title, the author, and the content. We also want to add some technical values in it such as the ID, createdAt, etc. These values will be represented as fields in the model.
  3. Some getters and setters for some fields
func TestArticleModel(t *testing.T) {
var article *model.Article

t.Run("test_constructor", func(t *testing.T) {
article = model.NewArticle()

assert.NotNil(t, article, "article should not be nil")
})
}
type Article struct {
}

func NewArticle() *Article {
return &Article{}
}
t.Run("test_fields", func(t *testing.T) {
article = model.NewArticle()

_ = article.Id
_ = article.Title
_ = article.Content
_ = article.Author
_ = article.CreatedAt
_ = article.CreatedBy
_ = article.UpdatedAt
_ = article.UpdatedBy

assert.NotNil(t, article, "article should not be nil")
})
type Article struct {
Id int64
Title string
Content string
Author string
CreatedAt int64
CreatedBy string
UpdatedAt int64
UpdatedBy string
}
func TestArticleModel(t *testing.T) {
article := model.NewArticle()

t.Run("test_constructor", func(t *testing.T) {
assert.NotNil(t, article, "article should not be nil")
})

t.Run("test_fields", func(t *testing.T) {
_ = article.Id
_ = article.Title
_ = article.Content
_ = article.Author
_ = article.CreatedAt
_ = article.CreatedBy
_ = article.UpdatedAt
_ = article.UpdatedBy

assert.NotNil(t, article, "article should not be nil")
})
}
t.Run("test_getter", func(t *testing.T) {
assert.Empty(t, article.Id(), "id should be empty")
assert.Empty(t, article.Title(), "title should be empty")
assert.Empty(t, article.Content(), "content should be empty")
assert.Empty(t, article.Author(), "author should be empty")
assert.Empty(t, article.CreatedAt(), "createdAt should be empty")
assert.Empty(t, article.CreatedBy(), "createdBy should be empty")
assert.Empty(t, article.UpdatedAt(), "updatedAt should be empty")
assert.Empty(t, article.UpdatedBy(), "updatedBy should be empty")
})

t.Run("test_setter", func(t *testing.T) {
article.SetTitle("a title")
article.SetContent("some contents")
article.SetAuthor("an author")
article.SetCreatedBy("a creator")
article.SetUpdatedBy("an updater")

assert.Equal(t, "a title", article.Title(), "title should be set")
assert.Equal(t, "some contents", article.Content(), "content should be set")
assert.Equal(t, "an author", article.Author(), "author should be set")
assert.Equal(t, "a creator", article.CreatedBy(), "createdBy should be set")
assert.Equal(t, "an updater", article.UpdatedBy(), "updatedBy should be set")
})
// ....previous implementation codefunc (a Article) Id() int64 {
return a.id
}

func (a Article) Title() string {
return a.title
}

func (a *Article) SetTitle(title string) {
a.title = title
}

func (a Article) Content() string {
return a.content
}

func (a *Article) SetContent(content string) {
a.content = content
}

func (a Article) Author() string {
return a.author
}

func (a *Article) SetAuthor(author string) {
a.author = author
}

func (a Article) CreatedAt() int64 {
return a.createdAt
}

func (a Article) CreatedBy() string {
return a.createdBy
}

func (a *Article) SetCreatedBy(createdBy string) {
a.createdBy = createdBy
}

func (a Article) UpdatedAt() int64 {
return a.updatedAt
}

func (a Article) UpdatedBy() string {
return a.updatedBy
}

func (a *Article) SetUpdatedBy(updatedBy string) {
a.updatedBy = updatedBy
}
type Article struct {
id int64
title string
content string
author string
createdAt int64
createdBy string
updatedAt int64
updatedBy string
}
package model_test

import (
"testing"

"github.com/pegasus37/blogpost-backend/app/model"
"github.com/stretchr/testify/assert"
)

func TestArticleModel(t *testing.T) {
article := model.NewArticle()

t.Run("test_new_article", func(t *testing.T) {
assert.NotNil(t, article, "article should not be nil")
})

t.Run("test_getter", func(t *testing.T) {
assert.Empty(t, article.Id(), "id should be empty")
assert.Empty(t, article.Title(), "title should be empty")
assert.Empty(t, article.Content(), "content should be empty")
assert.Empty(t, article.Author(), "author should be empty")
assert.Empty(t, article.CreatedAt(), "createdAt should be empty")
assert.Empty(t, article.CreatedBy(), "createdBy should be empty")
assert.Empty(t, article.UpdatedAt(), "updatedAt should be empty")
assert.Empty(t, article.UpdatedBy(), "updatedBy should be empty")
})

t.Run("test_setter", func(t *testing.T) {
article.SetTitle("a title")
article.SetContent("some contents")
article.SetAuthor("an author")
article.SetCreatedBy("a creator")
article.SetUpdatedBy("an updater")

assert.Equal(t, "a title", article.Title(), "title should be set")
assert.Equal(t, "some contents", article.Content(), "content should be set")
assert.Equal(t, "an author", article.Author(), "author should be set")
assert.Equal(t, "a creator", article.CreatedBy(), "createdBy should be set")
assert.Equal(t, "an updater", article.UpdatedBy(), "updatedBy should be set")
})
}
package model

type Article struct {
id int64
title string
content string
author string
createdAt int64
createdBy string
updatedAt int64
updatedBy string
}

func NewArticle() *Article {
return &Article{}
}

func (a Article) Id() int64 {
return a.id
}

func (a Article) Title() string {
return a.title
}

func (a *Article) SetTitle(title string) {
a.title = title
}

func (a Article) Content() string {
return a.content
}

func (a *Article) SetContent(content string) {
a.content = content
}

func (a Article) Author() string {
return a.author
}

func (a *Article) SetAuthor(author string) {
a.author = author
}

func (a Article) CreatedAt() int64 {
return a.createdAt
}

func (a Article) CreatedBy() string {
return a.createdBy
}

func (a *Article) SetCreatedBy(createdBy string) {
a.createdBy = createdBy
}

func (a Article) UpdatedAt() int64 {
return a.updatedAt
}

func (a Article) UpdatedBy() string {
return a.updatedBy
}

func (a *Article) SetUpdatedBy(updatedBy string) {
a.updatedBy = updatedBy
}

Conclusion

--

--

--

Spending most time as Software Engineer

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

How to Make a Camera Shake Feature in Unity

Quick tips on removing failed Docker container and images

Using Azure Cognitive Service Computer Vision AI to read text from an image

Pentesting LDAP Servers

Aggregation vs. Composition in Object Oriented Programming

Acronyms Every Web Developer Should Know

DeviseInvitable + Rails API

Utilizing CSS grid layout to organize our web apps

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Syukri Mullia Adil P

Syukri Mullia Adil P

Spending most time as Software Engineer

More from Medium

CQRS & Event Sourcing III: the framework

Camunda Version 7.16: Migrating a Tasklist Plugin (Angular JS)

The two main Sing-ins methods in OAuth.

Angular, AWS Amplify manage mutiple environment diff based backend in easy way