Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confused about why it's useful to unit test dummy objects

I'm reading Clean Code: A Handbook of Agile Software Craftsmanship and one of the examples involves a Portfolio class and a TokyoStockExchange class. However, Portfolio is not very testable because it depends on TokyoStockExchange as an external API to determine the value of the portfolio and such is quite a volatile lookup and not conducive to testing.

So, they solve this by creating a common StockExchange interface and have TokyoStockExchange and DummyStockExchange both implement the base class. Thus, dependency inversion principle is attained and in the PortfolioTest class one can instantiate a DummyStockExchange, fix a stock price to a corporation, assign the DummyStockExchange instance to the portfolio, and add some stocks from that company to the portfolio, and then assert if the expected value is indeed the proper value. Here's the code:

public class PortfolioTest
{
    private DummyStockExchange exchange;
    private Portfolio portfolio;

    protected void setUp()
    {
        exchange = new DummyStockExchange();
        exchange.fix("MSFT", 100);
        portfolio = new Portfolio(exchange);
    }

    public void GivenFiveMSFTTotalShouldBe500()
    {
        portfolio.add(5, "MSFT");
        Assert.assertEquals(500, portfolio.value());
    }
}

My question, simply, is why?

We were trying test if the TokyoStockExchange class worked in tandem with the Portfolio class. Obviously if we create another class with a new method that sets a stock price and then give the portfolio five of those stocks then everything will work. It just seems.. useless to test. I understand that TokyoStockExchange is basically impossible to test with Portfolio because of the changing stock prices but I don't understand how subbing in a rather useless test helps the situation.

It all just seems akin to not knowing if our adder programs works but the only numbers available are randomly generated so we create a dummy class that gives us a 2 and test if 2 + 2 = 4. Well yeah, obviously that is true. We can still break TokyoStockExchange and the test will still succeed because it's testing another class. If anything this all seems deceptive and it also results in having to write additional code just to test something we know is going to work.

I think this is the biggest problem I have with understanding Unit Testing at this point. I know that I'm wrong I just have failed to see the light I guess. Hopefully someone can help me out.

like image 215
John Smith Avatar asked Aug 17 '12 02:08

John Smith


People also ask

Why unit testing is useful?

Unit testing ensures that all code meets quality standards before it's deployed. This ensures a reliable engineering environment where quality is paramount. Over the course of the product development life cycle, unit testing saves time and money, and helps developers write better code, more efficiently.

Why should you use a mocks fakes in writing test cases?

You use mocks when you don't want to invoke production code or when there is no easy way to verify, that intended code was executed. There is no return value and no easy way to check system state change. An example can be a functionality that calls e-mail sending service.

What is dummy in unit testing?

Dummies, as the name implies, are simple objects that serve no real purpose other than being there when they're required. Their purpose is to be there when the syntax requires it. For example, imagine having to call a function that takes 3 arguments, with the first one being another function (an external dependency).

Should you mock in unit tests?

It is unlikely for mocking to be applicable in unit tests, as that means there is a part of the system the unit depends on, making that unit less isolated and less subjected to unit testing. Whenever you reach out to mock things in a unit test that is a good sign you are in fact writing an integration test.


1 Answers

The idea is that you would want to test the logic in the Portfolio class in isolation from TokyoStockExchange. If you use a mock framework like Moq or Rhino Mocks, then you can easily simulate different outputs and behaviors from TokyoStockExchange and write unit tests to make sure that Portfolio responds correctly. You would write separate unit tests for the TokyoStockExchange class.

This is not to say that you don't need integration testing between the two classes. It's just hard to properly verify all scenarios without the use of mock objects.

It's hard to understand the value with such a simple class as an example, but given a more complex class where you need to verify test cases for situations which are hard to or impossible to arrange on a "live" class, unit testing becomes much more important.

like image 149
Jacob Avatar answered Sep 22 '22 20:09

Jacob