0

I'm just beginning to Unit Test with my projects, but I still face a problem that's throwing me off. I really want to knuckle down and get to grips with Unit Testing because I know the long term benefits are worth the effort to learn.

I work extensively with the Twitter on an almost daily basis. I create a number of applications that work with Twitter.

In a real case scenario if I want to run a Unit Test to test whether the login was successful (not using the API in this case) how would I test this is true in the Unit Test? What I would usually do in production code is test to see whether the user ID is set on the page, or whether a certain cookie exists that only a logged in user would have. Then failing that I throw an exception.

But how would I test this in a Unit Test?

Would it be the same as how I would do it in production code? For example testing to see if a known cookie exists that only a logged in user has?

There are a number of scenarios like this that I really struggle to wrap my head around when thinking in terms of Unit Testing.

I know it can get kinda tricky when building applications that rely on third parties because the third party could change the way they work and your tests are useless until you've changed them.

James Jeffery
  • 12,093
  • 19
  • 74
  • 108

2 Answers2

1

When it comes to unittest an API or writing a cookie you can't/shouldn't test the existance of the cookie or that the API has accepted your request.

You know the format and values that are needed for a positive API request. When you test an API you usually hardcode the data to see if everything works with it. In case of your unittest you check if the needed values you normally send to the API have the expected format where the API works without errors. Your unittests are not supposed to test the API itself.

The same with cookies. You only test that the function/method is called with the expected data where a cookie is written without errors. You don't test something like a browser in a unittest.

SenseException
  • 1,015
  • 12
  • 14
1

The kind of high-level test that you manually perform on your application (e.g. manually logging in and then checking for some cookie) would probably not be called "Unit Test". Unit Tests, as the name suggests, should test small components of your application.

See this explanation of different types of test.

When you are working with external services, a common strategy is to create Mocks of their API. They allow you to check if your application is making the correct requests and is correctly processing the results - without actually connecting to the API.

An example:

Let's say your application has a class User. You can set username and password for a user and then tell it to login() to an external system. You would expect your application to make a request to that API, using the username and password that you set.

This can be roughly translated to a PHPUnit test like this:

public function testLogin() {
    // We create a mock of an existing wrapper class for the API
    $mockAPI = $this->getMock('ApiWrapperClass');

    // Create a new User instance, passing the mock API as a dependency
    $user = new User($mockApi);

    $user->username = "Test user";
    $user->password = "secret";

    // Now we set up the expectation of what should happen
    $mockApi->expects($this->once())
             ->method('login')
             ->with(
                 $this->equalTo("Test user"),
                 $this->equalTo("secret")
             )
             ->will($this->returnValue(TRUE));

    // Now we can call the actual function that we are testing
    $user->login();
}

The mock API will simply return true to emulate a successful login.

The PHPUnit documentation has a chapter on Mock objects.

Community
  • 1
  • 1
pixelistik
  • 7,541
  • 3
  • 32
  • 42