1

I was reading the following article

Unit testing an API

This article is about unit testing an API and the methods on a class through the interface. What I do not seem to grasp is the fact that in my idea you would want to test the method implementation / functionality of the 'real' methods?

So If I implement the method 'GetById', I would want to test the functionality of that function. However the Article shows how to create a Fake and test the Fake implementation of 'GetById'. This way you have two different definitions and testing just a 'totally different method / piece of code' and not the implementation / code you would like to see tested in the first place?

Maybe I am missing the point of unit tests here?

1
  • I didn't read all, but it look like a Mock project to me.There is answer about mocking here link Commented May 10, 2019 at 12:36

3 Answers 3

4

So If I implement the method 'GetById', I would want to test the functionality of that function.

Sure, and these tests would go in a ShoppingCartServiceTest class.

However the Article shows how to create a Fake and test the Fake implementation of 'GetById'.

Observe the test class of the article is ShoppingCartControllerTest. It is testing the controller, the class contains the endpoints:

// DELETE api/shoppingcart/5
[HttpDelete("{id}")]
public ActionResult Remove(Guid id)

And this class depends on a service (which fetches the data itself):

var existingItem = _service.GetById(id);

ShoppingCartControllerTest class is not worried about testing if the fetching is correct, but that the Controller calls the service in the correct moments and performs the necessary actions:

// Code this class wants to test
var existingItem = _service.GetById(id);

if (existingItem == null)
{
    return NotFound();
}

 _service.Remove(id);
 return Ok();

For this reason, one should create a Fake of the service, putting in control of the test the behavior of the service and allowing test isolation to the behavior of the Controller. The Controller class is designed in order to get the service injected - and this service can be a real implementation or a fake.

public ShoppingCartControllerTest()
 {
     _service = new ShoppingCartServiceFake();
     _controller = new ShoppingCartController(_service);
 }

Instead of a fake, the test class could have created other types of mocks, e.g. stubs or spies

To test GetById, you would go through a similar process:

  • Refactor the Service implementation so it get its dependencies in the constructor;
  • Create mocks for the dependencies;
  • In the ServiceTest class, instantiate the mocks and inject them in the Service implementation;
  • Exercise the Service implementation and checking its behavior, assuming the mock behavior of the dependencies.

OBS: The concerns of the article are not what most people call API Testing. It is really unit testing of class which happens to be the boundary of an API. API Testing usually refers to Integration Testing (or Integrated Testing to be more specific).

3

The real GetById probably accesses a database to get the data associated with the ID. In order to prevent the test becoming an end-to-end/integration test you will need to fake a part of your application. Maybe the example is oversimplified.

I would read into a ports and adapter architecture and how to test it in the book Growing Object-Oriented Software Guided by Tests, instead learning from just blogs.

2

How I'm reading it, they confusingly refer to 2 different bits of code as GetById here.

In the first instance they're referring to this method on the ShoppingCartController:

public ActionResult<ShoppingItem> Get(Guid id)

This is the method that they are unit testing.

In the second instance they're referring to a piece of code that isn't currently under test, this method on the IShoppingCartService

ShoppingItem GetById(Guid id);

As Niels says, this method on the IShoppingCartService is mocked/faked because it's outside the scope of a unit test.

I think the confusion when reading this page comes from the subheading "Testing the GetById method". What they really appear to mean is "Testing the Get(Guid) method". As you mention, there would be no point in testing the GetById method from the service as it is fake.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.