Reputation: 276
Below is the method i want to test. I am using TestNG framework for unit testing.
class Random{
List<String> namesOfLinks;
public List<String> methodIwantToTest(List<String> cktNames) {
Map<String, Graph> maps = DataBaseReader.getGraphs(cktNames);
for (Entry<String, Graph> entry : maps.entrySet()) {
graphList.add(entry.getValue().getName());
}
}
return namesOfLinks;
}
I am writing the test cases for the method "methodIwantToTest" in the above class. I can provide some dummy cktNames and get the method to execute like below.
@Test (dataProvider = "dp")
public void test_methodIwantToTest(List<String> cktNames, List<String> expectedLinkNames){
Random rm = new Random();
List<String> actual = rm.methodIwantToTest(cktNames);
Assert.assertEquals(actual,expectedLinkNames);
}
Now comes the problem. When the actual method is executing when i invoke it on the 'rm' reference, it has a static method call to another API. It has to return something in order for my "method" to work. I searched the internet and found "easymock" as a solution. But i am unable to use "easyMock" to mock the static method (DataBaseReader.getGraphs()). I have to mock that method so that it returns a map of the defined type. Any suggestions would be great. Thanks !!
Other questions deal with how to test static methods. But mine is about mocking a static method while testing a instance method.
Upvotes: 0
Views: 1252
Reputation: 38000
I would recommend using the Adapter pattern in combination with the Dependency Injection technique. Create an interface that contains all the methods you want to mock:
public interface IDatabase {
Map<String, Graph> getGraphs(List<String> names);
}
Obviously, Database
doesn't implement the interface you just invented (and the method is static
anyway), but you can create an adapter class:
public class DataBaseReaderAdapter implements IDatabase {
public Map<String, Graph> getGraphs(List<String> names) {
return DataBaseReader.getGraphs(names);
}
}
Take an instance of this class as a constructor parameter in the class you want to test:
public class Random {
private readonly IDatabase _database;
public Random(IDatabase database) {
_database = database;
}
}
and when you want to call the method:
Map<String, Graph> maps = _database.getGraphs(cktNames);
In your test, use any mocking framework to create a mock of IDatabase
, and pass that mock to Random
.
While this technique might seem pretty involved at first, it tends to lead to better designs in which the dependencies of a class are more visible and everything becomes easier to test.
Upvotes: 1
Reputation: 16894
You need PowerMock to do mock static methods directly. See https://github.com/jayway/powermock/wiki/TestNG_usage
Upvotes: 4