While unit testing you are not expected to test with a database, or at least, not with a database you haven't prepared for unit testing. Testing with a database, and as such, testing different layers of your application at the same time is generally seen as integration tests. With unit tests you are supposed to test only what your method does, what it returns depending on different parameters, and when (or not) it should fail.
It is very much expected that in your method you make calls to X methods from other classes. You are not testing these X methods so what you have to do is to mock these methods.
I suppose you're writing your code in Java, in that case you have great mocking frameworks such as Mockito which may be helpful to you. Whether or not you use a mocking framework is your choice, I'll just say they'll save you a lot of time and the one I mentioned at least is really not complicated.
If you just want to write your own mock to experiment, then suppose you have the following CustomerRepository
class:
public class CustomerRepository {
public CustomerDTO getCustomer(int id) {
...
}
}
You can write your own mocked and dirty CustomerRepository
class the following way:
public class MockedCustomerRepository extends CustomerRepository {
public boolean bThrowDatabaseException;
public boolean bReturnNull;
public boolean bReturnCustomerWrongId;
public boolean bReturnCustomerWithId;
public CustomerDTO getCustomer(int id) {
if(bThrowDatabaseException) {
throw new DatabaseException("xxx");
} else if(bReturnNull) {
return null;
} else if(bReturnCustomerWrongId) {
throw new CustomerNotExistException(id);
} else if(bReturnCustomerWithId) {
return new CustomerDTO(id);
}
}
}
Then, in your test case you basically replace your "standard" instance of CustomerRepository
with a mocked instance that will allow you to test your method for various outcomes of getCustomer
:
public class CustomerRestTest {
public void testGetCustomer_databaseFailure() {
MockedCustomerRepository dto = new MockedCustomerRepository();
dto.bThrowDataBaseException = true;
yRestClass rest = new MyRestClass();
rest.dto = dto;
rest.getCustomer(0);
// depending on what you do in your getCustomer method, you should check if you catched the exception, or let it pass, etc.. Make your assertions here
public void testGetCustomer_customerNotExist() {
// etc.
}
}
Generally, every test method should test one thing only, this helps keep your tests small and focused on one task.
I'm going to repeat it :-) Writing a whole mocked class takes some time as you see. Consider using a mocking framework, the less one writes code, the less errors one makes, right? Mocking a method that throws an exception, or returns a given value for a given parameter is a piece of cake and takes 2 or 3 lines (with mockito at least)
Hope that helps testing your REST method.
Your understanding of Integration Testing may be only partially correct.
You said:
I know that integration testing means integrating unit tested modules and testing for interface errors etc.
And yes, integration testing involves integrating together modules that have (preferably) been unit tested to verify they play nicely with each other.
The next portion is where I think there may be some confusion.
If by interface
you mean user interface then your understanding is incorrect. On the other hand, if you mean software Interface as is commonly used in OO programming, then your understanding is OK.
Integration testing is agnostic to front-end / back-end / middle-tier / n-layer / blah-blah-blah. As the SWEBOK section on Integration testing puts it:
Integration testing is the process of verifying the interaction between software components. Classical integration testing strategies, such as top-down or bottom-up, are used with traditional, hierarchically structured software.
Modern systematic integration strategies are rather architecture-driven, which implies integrating the software components or subsystems based on identified functional threads. Integration testing is a continuous activity, at each stage of which software engineers must abstract away lower-level perspectives and concentrate on the perspectives of the level they are integrating. Except for small, simple software, systematic, incremental integration testing strategies are usually preferred to putting all the components together at once, which is pictorially called “big bang” testing.
Wikipedia's entry on Integration Testing isn't bad either:
Integration testing (sometimes called Integration and Testing, abbreviated "I&T") is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.
So I think some of your confusion stems from worrying about which layer is being involved and how that rolls into what your organization is calling "Integration Testing." It may very well be that your organization is using a less-than-precise variation of the term.
Have a look at SWEBOK's section on Testing to get a better understanding of the various classifications of testing (including unit, system, and usability). That should help sort out the remainder of your questions regarding which testing is which and what aspects should be tested at what stages of Testing.
SWEBOK stands for Software Engineering Body of Knowledge
Best Answer
If you do not own the REST API's, your responsibility ends with them
You need tests that check if your application calls the API under your control correctly. Therefore, use the actual application with the actual service (the one you control) but calling mocked services (the ones you don't control).
So...