junit test case about #override method - java

I am working on the Junit test case and the grading scheme is based on the coverage of the code.
I meet a problem about some #override method inside a method because it seems like I can not call that method.
Just like the example below.
public void showFollowersList(PagableResponseList<User> followers) {
m_itemList.addListener(SWT.Resize, new Listener() {
#Override
public void handleEvent(Event arg0) {
m_itemList.setLayoutData(new RowData(m_itemList.getBounds().width,
m_itemList.getBounds().height));
m_rightFrame.layout();
m_rightFrame.pack();
}
});
}
addMouseTrackListener(new MouseTrackListener() {
#Override
public void mouseHover(MouseEvent arg0) {
}
#Override
public void mouseExit(MouseEvent arg0) {
Rectangle rect = HoverClickableComposite.this.getClientArea();
if (!m_clicked && !rect.contains(arg0.x, arg0.y)) {
setBackground(m_origColor);
}
}
How can I call or cover the method like handleEvent , mouseExit and mouseHover ?

If it helps, I think someone's done a very good job at making showFollowersList un-testable. Was that deliberate?
If so, the correct answer might not actually be a set of test code, but a very low coverage score and a list of recommendations for changing the class to make it more testable...
The only way to test it at the moment would be to set things up, poke it, and check what happens.
And that would only work if you can cause a handleEvent call to be fired on your object, and certain methods were available on the class:getList, getListenerCount, etc. Then, something like:
testObject.showFollowersList(followers);
// All that method does is add listener. So check that listener got added
assertEquals(1, testObject.getList().getListenerCount());
// Now check that inner handlers behave correctly
testObject.getList().fireEvent();
// This should have created a new RowData in the list
assertNotNull(testObject.getList().getLayoutData());
But if you don't have those methods available, then it's definitely not a good idea to add them and expose the List just for the sake of Unit Testing.
Another problem is the GUI. Your Unit Tests won't have a GUI. So, your m_rightFrame will probably be null (and even if it isn't, the underlying AWT classes will be).

It is not a method 'inside a method', it is a method of an anonymous class.
Usually, with SWT or Swing programming, it is the functional (business) aspect of the code that requires much test coverage, and not the scaffolding (handlers etc.)
However, if this is what is required, there are at least two options -
Do not use anonymous inner classes for the handlers - give them names in the same package.
Use a mocking framework like Powermock with JUnit and pass mocked SWT event objects to invoke handlers so that you have coverage.

Related

How to set Mock to have a default behavior and can override it in some test

I want to mock a dependency and return a default value in most test cases since most of them should not care about the values returned but there are some certain cases like I would like to test like the dependency returns some weird values or just throw. So I am modeling it in this way. Most cases, it should return a nice and valid value.
Test Setup which return the 20L by default for all test classes.
Dependency dependency = Mockito.mock(Dependency.class);
when(dependency.returnSomeVal()).thenReturn(20L);
In a specific test cases class, I would like to override the behavior like below:
when(dependency.returnSomeVal()).thenThrow(); //failure cases
when(dependency.returnSomeVal()).thenReturn(Weird_Val); //failure cases
But I don't find a good solution to override the existing behavior? Any idea?
You can reset the mock and add behavior. In the test, do
Mockito.reset(dependency);
when(dependency.returnSomeVal()).thenThrow(); //failure cases
when(dependency.returnSomeVal()).thenReturn(Weird_Val); //failure cases
Resetting will remove all mocked behavior on this class though. If you want to remock only some methods, then you have to create the mock from scratch.
I ended using myself this pattern to mock a bunch of methods of a class providing configurations.
In a #Before method I setup a bunch of stubs for a mocked object that provide a correct configuration for each test. Afterwards, in each test it was extremely convenient to only override one of those stubs to provide a different configuration and test a different error case.
I think the response from Hari Menon is correct but it somehow defeats the purpose explained in the question. If the mock is reset, all the stubs would need to be added again, making this pattern very confusing (it would be better to not use any overriding than using reset in this case, the code would be way more straightforward).
The comments added to the question provide indeed an indirect answer on how to achieve this, and why it works, but it took me a bit to get it working.
In spite of one of the comments, I made everything work by using in my #Before fixture when().thenReturn() and overriding the concrete stub with doReturn().when()
Example:
public class WorkerTest {
private ConfigProvider mockedConfigProvider = mock(ConfigProvider.class);
#Before
public void setup() {
// Setup stubs with a correct config
when(mockedConfigProvider.getValue("property1")).thenReturn("value1");
when(mockedConfigProvider.getValue("property2")).thenReturn("value2");
when(mockedConfigProvider.getValue("property3")).thenReturn("value3");
when(mockedConfigProvider.getValue("property4")).thenReturn("value4");
}
#Test
public void test_GoodConfig(){
// The config object gets injected in the test worker
Worker testWorker = new Worker(mockedConfigProvider);
// testWorker.execute() returns true if everything went well
assertTrue(testWorker.execute());
}
#Test
public void test_BadConfigProp1(){
// Test now with a broken 'property1', overriding that stub.
doReturn(null).when(mockedConfigProvider).getValue("property1");
Worker testWorker = new Worker(mockedConfigProvider);
// testWorker.execute() returns false if there is a problem.
assertFalse(testWorker.execute());
}
#Test
public void test_BadConfigProp2(){
// This test needs to only override the result of property2
doReturn("crazy result").when(mockedConfigProvider).getValue("property2");
...
}

Is it possible to have a global setup method in Spock test?

I am a developer on a Grails/Groovy application which uses Spock as its framework for unit testing. The project has around 1000 unit tests, and I would essentially like to perform a specific mock / operation before running all tests. Preferably it should only be executed once, alternatively before each test - or before some large subset of all the tests. I imagine that it out to be possible to have a “global” setup method which all tests can extend. Is this possible?
Preferably it should only be executed once, alternatively before each
test - or before some large subset of all the tests. I imagine that it
out to be possible to have a “global” setup method which all tests can
extend. Is this possible?
Yes, it is possible. The specifics of how best to do it will depend on specifically what you want to accomplish but global extensions are likely candidates. See the "Writing Custom Extensions" section of http://spockframework.org/spock/docs/1.3/extensions.html for a lot of detail. There is a lot of flexibility there. We had great success writing custom extensions for Micronaut.
I hope that helps.
We ended up doing the following. First we defined a class implementing IAnnotationDrivenExtension interface:
class MockConfigMapExtension implements IAnnotationDrivenExtension<MockConfigMap> {
#Override
void visitSpecAnnotation(MockConfigMap annotation, SpecInfo spec) {
// WRITE THE RELEVANT STARTUP CODE HERE
}
#Override
void visitFeatureAnnotation(MockConfigMap annotation, FeatureInfo feature) {
}
#Override
void visitFixtureAnnotation(MockConfigMap annotation, MethodInfo fixtureMethod) {
}
#Override
void visitFieldAnnotation(MockConfigMap annotation, FieldInfo field) {
}
#Override
void visitSpec(SpecInfo spec) {
}
}
where we defined this trivial annotation:
#Retention(RetentionPolicy.RUNTIME)
#Target([ElementType.TYPE])
#ExtensionAnnotation(MockConfigMapExtension.class)
#interface MockConfigMap {
}
Now, whenever we annotate a Spec class with the MockConfigMap annotation, the visitSpecAnnotation method is invoked, and we get the desired behaviour.

Mockito - Mock a statement to test the inline implementation

I am trying to mock a statement which has an inline implementation. I want to test the implementation:
commonUtils.getCommandStack().execute(new RecordingCommand(commonUtils.getTed()) {
#Override
protected void doExecute() {
//Statements needs to be tested
}
});
I mocked commonUtils.getCommandStack() and commonUtils.getTed().
I tried two approaches but none of them letting the control to inside the doExecute() method.
I tried 2 approaches but none of them working for me.
Approach 1:
Mocking the inline implementation like below but did not work
`TransactionalEditingDomain mockTed = Mockito.mock(TransactionalEditingDomain.class);
Mockito.when(mockCommonUtils.getTed()).thenReturn(mockTed);
CommandStack mockCommandStack = Mockito.mock(CommandStack.class);
Mockito.when(mockTed.getCommandStack()).thenReturn(mockCommandStack);
Mockito.doNothing().when(mockCommandStack).execute(new RecordingCommand(mockTed) {
#Override
protected void doExecute() {
}
});`
Approach 2
Mocking the RecordingCommand like below but did not work
`TransactionalEditingDomain mockTed = Mockito.mock(TransactionalEditingDomain.class);
Mockito.when(mockCommonUtils.getTed()).thenReturn(mockTed);
CommandStack mockCommandStack = Mockito.mock(CommandStack.class);
Mockito.when(mockTed.getCommandStack()).thenReturn(mockCommandStack);
Command recordingCommandMock = Mockito.mock(Command.class);
Mockito.doNothing().when(mockCommandStack).execute(recordingCommandMock);`
Please help me what should I do to get the control inside doExecute() method because I have many methods like this in util.
You can write your own code to answer the mocked call. In this case, you can retrieve the object that is passed in and call it from there.
Mockito.when(mockCommandStack.execute()).thenAnswer(invocation -> {
RecordingCommand commandReceived = (RecordingCommand)invocation.getArguments[0];
commandReceived.doExecute(); // or whatever method applies here
});
Unittest verify public observable behavior (return values and/or communication with dependencies) of the unit under test.
Your inline implementation is an implementation detail which unittest expicitly do not test.
You should refactor you production code so the the inline implementation becomes a testable unit of its own.

Is it possible to inject lines of code at specific positions through annotations

I want to inject some code through annotations in java.
The plan is I have two methods beginAction() and endAction(). I want to annotate a method such that before executing the statements in the method the beginAction() will be put and after finishing executing them the endAction() will be put automatically. Is it possible. If yes please suggest me how to do.
#MyAnnotation
public void myMethod(){
// Statement 1;
// Statement 2;
}
At runtime the beginAction() and endAction() should be injected in the method through the annotation. That is it should become like the following at runtime.
public void myMethod{
beginAction();
// Statement 1;
// Statement 2;
endAction();
}
It looks like you need aspects. AspectJ is the most popular library in this case. You can read more about it here: https://eclipse.org/aspectj/docs.php
And here's the example of such aspect in use:
Class with intercepted method:
public class YourClass {
public void yourMethod() {
// Method's code
}
}
Aspect itself:
#Aspect
public class LoggingAspect {
#Around("execution(* your.package.YourClass.yourMethod(..))")
public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Do something before YourClass.yourMethod");
joinPoint.proceed(); //continue on the intercepted method
System.out.println("Do something after YourClass.yourMethod");
}
}
You can't do it using just plain Java. However, there is a Java-like language that does allow this. It's called Xtend. It compiles to Java, not bytecode, so it benefits from all the wonderful things your Java compiler does.
It started life as an Eclipse project, but is now also available for IntelliJ.
One of its many features is a thing called "Active Annotations". They do exactly what you're asking for: they allow you to participate in the code generation process, so you can insert your beginAction() and endAction() methods as you want.
See http://www.eclipse.org/xtend/documentation/204_activeannotations.html for more info on Active Annotations.

List the names of methods being invoked

I'd like to have a reflection-like solution for displaying the methods which are called.
Example:
public class Foo {
public void bar() {
new Y().x();
}
}
public class Y {
public void x() {
}
}
public class Main {
public static void main(String[] args) {
// SETTING UP THE MAGIC
new Foo().bar();
new Y().x();
}
}
The output should be:
1. Foo.bar
1.2 Y.x
2. Y.x
Optimally there could be an event handler which would be fired every time a method is called(and some info could be passed as a parameter).
PS: I don't want to use this in a production environment, I only need this for displaying output in a skeleton app without dummy copy-paste.
I would use aspectj to define an aspect which writes log messages for every method call. You can find an example here: Tracing Java Method Execution with AspectJ. or here: Logging with AspectJ
The advantage of this solution is that you don't have to make any changes on your code. You will need some time to get into aspectj, but it meets your requirement very well.
You would have to build a profiler agent if you wanted to achieve this without having to pollute your code.
Take a look at this article, it shows you how to do it. Specifically, look at profiling aspects lower in that article.
Listing 2 is a profiling aspect that can be used to output the class name, method name, and a timestamp every time the JVM enters or leaves a method.

Categories