Start learning free

LESSON 136 OF 173 · BACKEND: TESTS AND RUNNING IT

Test a POST

Practice

Your tests so far only read the shop. A test can also add to it: http.Post sends a POST request. It takes the URL, the content type, here "application/json", and the body, for example strings.NewReader over a JSON string.

func (s *CustomerTests) TestAddCustomer() {
	server := httptest.NewServer(app)
	defer server.Close()
	body := strings.NewReader(`{"name": "Ana"}`)
	response, _ := http.Post(server.URL+"/customers", "application/json", body)
	s.Equal(201, response.StatusCode)
}

A 201 Created only says the app answered well. It doesn't prove that the new thing was saved. To know that, the test asks for it back with a GET, using the id from the answer, and checks that it gets the same thing.

In the shop, the Plant gets the next id, 5, and asking for product 5 must give back the very same product:

POST /products  {"name": "Plant", "price": 15, "category": "home"}
  →  201  {"id": 5, "name": "Plant", "price": 15, "category": "home"}
GET /products/5  →  the same product

The check runs your tests on the shop, then on two broken copies: one answers 201 but never saves the product, the other gives every new product the id 1. Your tests must pass on the shop and catch both copies:

Your tests on the shop:
  TestAddProduct ... ok
  TestOneProduct ... ok
  2 tests: OK
Your tests on a copy that answers 201 but never saves the product:
  TestAddProduct ... FAIL
    Not equal: expected map[category:home id:5 name:Plant price:15], actual map[error:Product not found]
  TestOneProduct ... ok
  2 tests: 1 failed, so they caught this bug
Your tests on a copy that gives every new product the id 1:
  TestAddProduct ... FAIL
    Not equal: expected map[category:home id:1 name:Plant price:15], actual map[category:kitchen id:1 name:Mug price:12]
  TestOneProduct ... ok
  2 tests: 1 failed, so they caught this bug

Your task: below TestOneProduct, write TestAddProduct. Start a test server for app, POST a Plant (price 15, category "home") to /products as "application/json", check that the status is 201, and decode the JSON answer into newProduct. Then GET /products/ followed by its id, decode that answer into product, and check that product equals newProduct.


Assignment
Follow the Coding Tutorial to write a test that POSTs a product and then GETs it back.


Hint
The id in newProduct["id"] is not text: turn it into text with fmt.Sprint(...) before you add it to "/products/". The second answer goes into the same response, so use = there, not :=. The last check compares the whole decoded GET answer with newProduct.


STEP 1 OF 9
    Ctrl + Enter to check