Can explain dependency injection
Dependency injection is the process of 'injecting' objects to replace current dependencies with a different object. This is often used to inject stubs to isolate the from its so that it can be tested in isolation.
A Foo
object normally depends on a Bar
object, but you can inject a BarStub
object so that the Foo
object no longer depends on a Bar
object. Now you can test the Foo
object in isolation from the Bar
object.
Can use dependency injection
Polymorphism can be used to implement dependency injection, as can be seen in the example given in [Quality Assurance → Testing → Unit Testing → Stubs] where a stub is injected to replace a dependency.
Here is another example of using polymorphism to implement dependency injection:
Suppose you want to unit test Payroll#totalSalary()
given below. The method depends on the SalaryManager
object to calculate the return value. Note how the setSalaryManager(SalaryManager)
can be used to inject a SalaryManager
object to replace the current SalaryManager
object.
class Payroll {
private SalaryManager manager = new SalaryManager();
private String[] employees;
void setEmployees(String[] employees) {
this.employees = employees;
}
void setSalaryManager(SalaryManager sm) {
this.manager = sm;
}
double totalSalary() {
double total = 0;
for (int i = 0; i < employees.length; i++) {
total += manager.getSalaryForEmployee(employees[i]);
}
return total;
}
}
class SalaryManager {
double getSalaryForEmployee(String empID) {
// code to access employee’s salary history
// code to calculate total salary paid and return it
}
}
During testing, you can inject a SalaryManagerStub
object to replace the SalaryManager
object.
class PayrollTest {
public static void main(String[] args) {
// test setup
Payroll p = new Payroll();
// dependency injection
p.setSalaryManager(new SalaryManagerStub());
// test case 1
p.setEmployees(new String[]{"E001", "E002"});
assertEquals(2500.0, p.totalSalary());
// test case 2
p.setEmployees(new String[]{"E001"});
assertEquals(1000.0, p.totalSalary());
// more tests ...
}
}
class SalaryManagerStub extends SalaryManager {
/** Returns hard coded values used for testing */
double getSalaryForEmployee(String empID) {
if (empID.equals("E001")) {
return 1000.0;
} else if (empID.equals("E002")) {
return 1500.0;
} else {
throw new Error("unknown id");
}
}
}
Exercises