Looking for a generic way to assert that a call to an aspect services method makes a call to a lower level service call by the same name.
Our application uses OSGI and aspect service where there are several implementations of the same interface with each implementation calling through to the lower layers, and likely doing some post processing. For example...
public interface ConfigService {
public List<String> getConfigurations();
}
public class ConfigServiceImpl implements ConfigService {
private volatile ConfigDAO dao;
#Override
public List<String> getConfigurations() {
List<String> configs = dao.getConfigurations();
// do something with configs
return configs;
}
}
public class ConfigDAO implements ConfigService {
#Override
List<String> getConfigurations() {
// database calls
return configs;
}
}
I would like to come up with a generic method, something along the lines of verifyCallsDelegate(configService, mockConfigDao, "getConfigurations");, that would allow me to write a bunch of one liners testing call through behavior instead of
configService().getConfigurations();
verify(mockConfigDao).getConfigurations();
This is a contrived example and I would likely like to take things a step further and assert that the value returned from mockConfigDao.getConfigurations() was what was returned from configService.getConfigurations() but once I get past getting the simplest test to work I will add that kind of smarts.
Can anyone suggest an implementation or like technique for my ```verifyCallsDelegate```` method above.
Related
I have a class similar to this:
public class QueueingCommandRunner {
private Status status;
private Map<Class<CommandHandler>, CommandHandler> queuedCommands;
private RunnerClass runnerClass;
private ExternalCommandRunnerRegistry externalCommandRunnerRegistry;
private ExternalCommandRunner externalCommandRunner;
public QueueingCommandRunner(ExternalCommandRunnerRegistry externalCommandRunnerRegistry,
RunnerClass runnerClass) {
this.externalCommandRunnerRegistry = externalCommandRunnerRegistry;
this.runnerClass = runnerClass;
this.queuedCommands = new LinkedHashMap<>();
this.status = Status.DOWN;
}
public void init() {
doSomeStuff();
externalCommandRunner = externalCommandRunnerRegistry.get(runnerClass);
externalCommandRunner.runListeningCommand(ListenableStatusCommand.class,
new ListenableStatusHandler(this::changeStatus));
}
public <T extends CommandHandler> void runCommand(Class<T> command, T commandHandler) {
if (status == UP) {
externalCommandRunner.run(command, commandHandler);
} else {
queuedCommands.put(command, commandHandler);
}
}
private void changeStatus(Status status) {
this.status = status;
if (status == UP) {
Iterator<Entry<Class<CommandHandler>, CommandHandler>> commandsIterator =
queuedCommands.iterator();
while (commandsIterator.hasNext()) {
<Entry<Class<CommandHandler>, CommandHandler>> queuedCommand = commandsIterator.next();
externalCommandRunner.run(queuedCommand.getKey(), queuedCommand.getValue());
commandsIterator.remove();
}
}
}
}
I omit stuff like synchronization. My question is, how to test queuing which is inside without using things like invocation of private methods via reflection? In particular I would like to know how to test changeStatus method since it is not directly run from any public method in this class. Is this class bad by design (from unit testing point of view)?
I am using JMockit for testing...
As it was mentioned in the comment - you test
desired public observable behavior
So, if you want to test private methods you need to make them public. I suggest to make it as interface:
public interface SomeInterface {
changeStatus(Status status);
}
Then inject implementation to your class:
public final class A {
private final SomeInterface someInterface;
public A(SomeInterface someInterface) {
this.someInterface = someInterface;
}
}
Then you can easily test SomeInterface implementation and mock if you need it in your class A.
So, I cannot give you the whole refactoring process for your particular case. But you can follow this guideline and you can encapsulate all private methods with interfaces that are tested easily. As I can see, you are using internal details of your class in private methods - these details should be encapsulated in interface implementation constructor (via another interfaces) and you will end up with small nice cohesive testable classes. Look through Command Pattern as it seems suitable for your case and try to follow SOLID which will also lead to testable code.
I see several problems with your design:
init() method. Which leads to temporal coupling as your class is not ready to use after construction;
your runCommand method is doing two things based on status. It's either run command or put it to map (which is hidden side-effect);
your changeStatus is also running comands.
You need to decouple those thins (running command, holding them and tracing status). Maybe encapsulate status of the command inside command itself. So the command will know how to work in its own way.
I find it hard to give this question a concret title, as I'm not really aware of how to name my type of problem. Any suggestions welcome.
I have a service to run logic that literally performs the same action (eg save a thumbnail), but contains completely different logic for different providers:
#Service
public class ThumbnailService {
public void saveForProvider1(Prov1 url) {
}
public void saveForProvider2(Prov2 url) {
//completely different logic than Provider1; also a different parameter Object "Prov2"
}
}
Problem 1: for any new provider I have to create an additional method in that ThumbnailService.
Now at a specific point, I want to run those methods async:
//basically just an async wrapper service
#Service
#Async
public class ThumbnailServiceAsync {
#Autowired
private ThumbnailService delegator;
public class asyncSaveForProvider1(Prov1 url) {
delegator.saveForProvider1(url);
}
public class asyncSaveForProvider2(Prov2 url) {
delegator.saveForProvider2(url);
}
}
Switching by anInteger variable where I know which number stands for which provider:
int provider;
switch (provider) {
case 1: thumbServiceAsync.asyncSaveForProvider1(url); break;
case 2: thumbServiceAsync.asyncSaveForProvider2(url); break;
default: throw NotSupportedException();
}
Problem 2: as you see I'm writing lots of code just for the sake of delegation to the specific provider routine. And I also have to touch at least those 3 classes mentioned when introduction any additional provider.
Question: how could I optimize this process? Especially regarding that by time more providers may be implemented. And also not only a thumbnail routine, but furhter methods that have to be implemented for every provider, but are different from their logic. Like "create a user for providerX", or "run some cleanup routine for providerX".
interface Provider {
void specificProviderCode();
}
public class Provider1 implements Provider {
public void specificProviderCode(){
}
}
public class ProviderFactory{
public static Provider createProvider(ProviderType providerType){
if(providerType.equals(ProviderType.TYPE_1){
return new Provider1();
}
}
}
#Service
public class ThumbnailService {
public void saveForProvider(Provider provider){
provider.specificProviderCode();
}
}
#Service
#Async
public class ThumbnailServiceAsync {
#Autowired
private ThumbnailService delegator;
public class asyncSaveForProvider(ProviderType providerType) {
Provider url = ProviderFactory.createprovider(providerType);
delegator.saveForProvider(url);
}
}
Now when you are adding new provider only there you need to make changes(to create new one with specific logic), both services will not be changed, which also means all callers to services do not need to change their code.
The Command Pattern is a great fit here.
Think of the save methods as instances of Runnable or Callable (the basic Command interfaces in Java). If ThumbnailService would wrap each unique save method along with its unique parameter into one of these Command interfaces, then ThumbnailServiceAsync could become a simple Executor with no knowledge of Providers. The switch statement goes away, because the Executor treats every Command the same: by invoking run() or call().
This leaves the question of closing ThumbnailService to modification. We'd like to eliminate knowledge of concrete Providers from that class as well. The obvious OOP approach would be to break the different logic up into separate classes, potentially into the Providers themselves. If you must wrap a common interface around the Providers, you may need to resort to serializing the different parameters e.g. as Strings, casting, or perhaps using reflection.
Code from Spring in Action :
public class DamselRescuingKnight implements Knight {
private RescueDamselQuest quest;
public DamselRescuingKnight() {
this.quest = new RescueDamselQuest();
}
public void embarkOnQuest() {
quest.embark();
}
}
public class BraveKnight implements Knight {
private Quest quest;
public BraveKnight(Quest quest) {
this.quest = quest;
}
public void embarkOnQuest() {
quest.embark();
}
}
public class BraveKnightTest {
#Test
public void knightShouldEmbarkOnQuest() {
Quest mockQuest = mock(Quest.class);
BraveKnight knight = new BraveKnight(mockQuest);
knight.embarkOnQuest();
verify(mockQuest, times(1)).embark();
}
}
I understand the use of dependency injection, which allows us to switch implementation without modifying the depending code.
The book says "terribly difficult to write a unit test ...".
However, I am not able to understand how it will be very difficult for unit-testing without dependency injection! My intuition refuses to co-operate !
Can you start writing junit/unit testing for the class "DamselRescuingKnight" and for any other better example class (without DI), to make me realize the point/stage at which DI makes unit testing easier ?
The difficulty in your above example comes when you try to test DamselRescuingKnight. Assume, you want to test that one (see below)
public class DamselRescuingKnight implements Knight {
private RescueDamselQuest quest;
public DamselRescuingKnight() {
this.quest = new RescueDamselQuest();
}
public void embarkOnQuest() {
quest.embark();
}
}
public class DamselRescuingKnightTest {
#Test
public void knightShouldEmbarkOnQuest() {
DamselRescuingKnight knight = new DamselRescuingKnight ();
knight.embarkOnQuest();
// now what?
}
}
how can you be sure that knight.embarkOnQuest() does actually do anything? The answer is that you can't because you can't access the quest instance it uses internally.
Now in order to be able to test such a class, you would add a getQuest() method to the Knight, and then also add a isEmbarked() method to Quest.
It is also quite fair to say, that this example is very simple, because the knight only calls the quest without parameters, and nothing else. If knight would interact with a quest and also get some weaponary from a Blacksmith, then you would also somehow need to allow access for that. You could probably do all the boilerplate to get that done. But then assume, you're passing parameters to blacksmith - how do you ensure that the passed parameters were correct? Or how do you ensure that the knight gets his/her weapon before going to the quest?
This is where dependency injection comes to the rescue. you can just create mocks (either by using a mock framework, or by implementing your own mocks) so that you can verify that your knight does the expected things.
The problem is of course the quest variable. You want to somehow check that the embark() method is invoked. Without being able to replace it with a mocked instance, this is very hard.
If the variable were protected instead of private, the test case could overwrite it by virtue of living in the same package.
You can also use Aspect-Oriented Programming to replace the variable.
But the easiest is if the code is written with dependency injection from the get-go.
You ask to see how AOP can be used. The following is an example of an AspectJ pointcut that you can use in a unit test to replace the RescueDamselQuest instance with a mocked one called MockRescueDamselQuest (apologies if I don't get the syntax exactly right, it has been a while since I used AspectJ):
aspect MockRescueDamselQuestInstantiations {
RescueDamselQuest around (): call(RescueDamselQuest.new()) {
return new MockRescueDamselQuest();
}
}
This will catch any instantiations of RescueDamselQuest (i.e. calls to new RescueDamselQuest()) and return a MockRescueDamselQuest object instead.
Given how much more wiring this requirest, I'd strongly suggest using dependency injection instead!
This perplexed me as well when I was reading this in Spring in Action. After reading above answers I wanted to add that when DI is not used then Junit method need to call method of object which is private (which is in accessible) and this object Quest is created in constructor of DamselRescuingKnight so test case for embarkQuest() can't be written. On contrary when using DI then you are externalizing object creation and Junit method can create that object so it will be accessible to it then can test emabarkQuest() which eventually need to test quest method
I'm trying to add unit tests to some legacy code that has a String class name passed to it and that creates an object implementing a particular handler interface using Class.newInstance(String className). I can control the class name I'm passing, I can get a pointer to the new handler object (via a getHandler() call), and I would like to observe calls to it using Mockito.
My current solution is:
Create a new test class TestHandler that implements the interface.
Have that test class contain a Mockito mock object that also implements the interface.
Manually pass through all the interface methods to the mock object.
Make the mock object accessible via a getMock() method.
Observe the object by making verify() calls to objectUnderTest.getHandler().getMock().
This works, but feels a little inelegant, especially having to manually write all the pass-thru methods.
Is there a better solution?
Fundamentally, you're running into the same problems as trying to test a newly-created instance using new; the Class.newInstance (probably properly Class.forName(foo).newInstance()) doesn't hurt you, but doesn't help you either.
As a side note, your TestHandler sounds like a general purpose delegate implementation, which sounds pretty useful anyway (particularly if you ever need to write a Handler wrapper). If it is, you might want to promote it to be adjacent to your Handler in your production code tree.
Though I recognize that you mention legacy code, this becomes very easy if you are allowed to refactor to include a testing seam. (Ignoring reflective exceptions here for ease of explanation.)
public ReturnType yourMethodUnderTest(String className) {
return yourMethodUnderTest(Class.newInstance(className));
}
/** Package private for testing. */
public ReturnType yourMethodUnderTest(Handler handler) {
return yourMethodUnderTest(Class.newInstance(className));
}
You could also extract the object creation and replace it in your test:
/** Instance field, package-private to replace in tests. */
Function<String, Handler> instanceCreator =
( x -> (Handler) Class.forName(x).newInstance());
public ReturnType yourMethodUnderTest(String className) {
Handler handler = instanceCreator.apply(className);
// ...
}
You could even just extract it to a method and replace it in your test:
public ReturnType yourMethodUnderTest(String className) {
Handler handler = createHandler(className);
// ...
}
/** Package private for testing. */
Handler createHandler(String className) {
return Class.forName(className).newInstance();
}
#Test public void yourTest() {
// Manually replace createHandler. You could also use a Mockito spy here.
ObjectUnderTest objectUnderTest = new ObjectUnderTest() {
#Override Handler createHandler(String className) {
return mock(Handler.class);
}
}
// ...
}
Side note: Even though Mockito creates a named dynamic type, you almost certainly will not be able to hack it in and allow your code to create it by name. This is because the call to mock registers the instance within Mockito's internal state.
// BAD: Unlikely to work
#Test public void yourTest() {
objectUnderTest.methodUnderTest(
mock(Handler.class).getClass().getName());
// ...
}
Create a public method where you will place the logic to fetch the newInstance of the class
ClassA objectClassA=createNewInstance(className);
likewise,and
public ClassA createInstance(String className){
return (ClassA) (Class.forName(className)).newInstance();
}
Now suppose we were creating an instance of classA inside of ClassB
then in TestClass of B, we can simply mock this createInstance method
doReturn(mockClassA).when(mockClassB).createInstance(className);
I defined some classes with, each one, several public methods with #Test annotation. All methods follow the same behavioral pattern (retrieve ressources from IDs, test if empty, log, call the real test for each line on the resource). So, I've externalized this behavior in an abstract class I instanciate on each method, like this:
#Test
public void someTest(){
new BasicTestPattern("X","Y","Z"){ // some parameters to retrieve resources
#Override
protected void testLine(){
someCheck1();
someCheck2();
}
}.run();
}
This solution eliminate 10-30 lines per test method.
Now, I want to go further with a custom annotation, like that:
#TestPattern(param1="X",param2="Y",param3="Z")
public void someTest(){
someCheck1();
someCheck2();
}
Finally I created a little framework to retrieve all the methods with this new annotation in order to instanciate BasicTestPattern and execute it. It is executed well in a TestCase subclass, like that:
TestCase junit_test = new TestCase(){
#Override
public void runTest() {
pattern.run();
}
};
junit_test.run();
However, no Test is displayed/listed in the JUnit view from Eclipse. I see only the number of tests succeeded.
How can I do that ? Thank you.
You probably will need to make your own custom Runner to find all the methods annotated with your #TestPattern method. (and probably also with #Test ?)
Then your test class will look like this:
#RunWith(YourRunner.class)
public class YourTest{
#TestPattern(param1="X",param2="Y",param3="Z")
public void someTest(){
...
}
#Test
public void anotherNormalTest(){
...
}
}
This Blog explains how to write custom Runners. But you can probably get away with extending BlockJUnit4ClassRunner to add the your special test methods to the list of tests to run.
I think you would only have to override the computeTestMethods() method which is how BlockJUnit4ClassRunner finds all the test methods to run (the methods annotated with #Test) you can override it to find the methods you annotated with your own annotation.
public class your TestRunner extends BlockJUnit4ClassRunner{
protected List<FrameworkMethod> computeTestMethods() {
//this is all the #Test annotated methods
List<FrameworkMethod> testAnnotatedMethods = super.computeTestMethods();
//these are all the methods with your #TestPattern annotation
List<FrameworkMethod> yourAnnotatedMethods = getTestClass().getAnnotatedMethods(TestPattern.class);
//do whatever you need to do to generate the test
//methods with the correct parameters based on
//the annotation ?
//Might need to make fake or
//synthetic FrameworkMethod instances?
...
//combine everyting into a single List
List<FrameworkMethod> allTestMethods =...
//finally return all the FrameworkMethods as a single list
return allTestMethods;
}
}
You might have to make your own FrameworkMethod implementation wrapper to get the info from the annotation and do whatever set up is required before invoking the method.
This will make it seamlessly integrate with normal JUnit classes and work with the JUnit IDE view
Good Luck