PowerMock not stubbing the right method - junit4

I am facing an weird PowerMock issue. Let me explain more in details.
My code:
#Service
public class TestMe {
#Autowired
private ClassA a;
#Autowired
private ClassB b;
#Autowired
private ClassStatic staticClass;
public void init(){
List<String> nameList = returnNames(); // Line#1
// Work with names
List<String> placeList = returnPlaces(); // Line#2
// Work with places
}
public List<String> returnNames(){
// Code to return list of names
}
public List<String> returnPlaces(){
// Code to return list of places
}
}
My Test Class
#RunWith(PowerMockRunner.class)
#PrepareForTest({ClassStatic.class})
public class TestMeTest {
#Mock
private ClassA aMock;
#Mock
private ClassB bMock;
#InjectMocks
private TestMe testMeMock;
#Test
public void testInit(){
List<String> listNames = ... // some list of names
List<String> listPlaces = ... // some list of places
when(testMeMock.returnNames()).thenReturn(listNames);
// listPlaces gets returned in Line#1 shown in the main code.
when(testMeMock.returnPlaces()).thenReturn(listPlaces);
testMeMock.init();
}
}
So, as you see in line#1 I get listPlaces instead of listNames. If I rearrange the when calls then I get listNames instead of listPlaces at Line#2.
Why PowerMock confuses with the methods? Or there is something else I am missing while working with PowerMock.

I could solve the issue by using thenReturn twice like below
when(testMeMock.returnNames()).thenReturn(listNames).thenReturn(listPlaces);
// Removed the returnPlaces() call
// when(testMeMock.returnPlaces()).thenReturn(listPlaces);
testMeMock.init();
But why can't PowerMock distinguish between two different method calls returnNames() and returnPlaces()??

A different perspective. This here:
#InjectMocks
private TestMe testMeMock;
and that:
when(testMeMock.returnPlaces()).thenReturn(listPlaces);
simply doesn't make sense together.
The #InjectMocks annotation is meant to create an instance of your class under test, which gets "filled" with the other mocks you created via the #Mock annotation. But then you use that class under test instance like it were a mock (by going when(testMeMock.foo())).
You should start by stepping back and clarifying for yourself what exactly you intend to do. Probably partial mocking, because you want to test your init() method, but you also intend to control what other methods on your class under test do.
Finally, you might also want to step back and re-think your overall design. To have public methods returning lists, that are also used on a public method that does the init, that simply sounds wrong, too.

Related

How to mock #PrePersist method?

How do I mock a #PrePersist method, e.g. preInit(), of an entity that I instantiate?
I'm using TestNG. EasyMock is prefered.
#Test(enabled = true)
public void testCreateOrder() {
// Instantiating the new mini order will automatically invoke the pre-persist method, which needs to be mocked/overwritten!
MiniOrder order = new MiniOrder();
order.setDate(new Date());
order.setCustomerId(32423423);
}
The MiniOrder.java is an entity that has a pre-persist method. Again, the one I like to mock/overwrite. E.g. this.id = 1; Alternatively one could also mock the IdGenerator.getNewId() method.
#PrePersist
protected void preInit(){
this.id = IdGenerator.getNewId();
}
I don't want the IdGenertor class to be called, because it attempts to grab a jndi resource. I just don't understand how to capture this pre-persist method in advance, so that it's not triggered ,respectively replaced by different code, before the object is fully instantiaded.
In this case, what you really want is to mock the IdGenerator dependency, which happens to be called from a #PrePersist method.
Using JMockit, the test can be written as follows:
#Test
public void createOrder()
{
new MockUp<IdGenerator>() {
// change as needed...
#Mock int getNewId() { return 123; }
};
MiniOrder order = new MiniOrder();
order.setDate(new Date());
order.setCustomerId(32423423);
}

Test cases in maven and eclipse

I use maven for managing dependencies in my project.
I have seen while writing test cases that some of them pass in eclipse while fail on maven build. I debugged it and found that there are static final members of classes being initialized once retain their values throughout the build. It is a multi-module project.
Is it possible to change the value of those final members for different test cases?
Please ask me if you want more clarification.
Any links/hints or ideas may be helpful.
Thanks.
The static final members are the Java way of expressing constants. First try to modify your test in such a way that it works with the values of these constants. If this is not possible, you can add a second constructor for testing purpose that overrides these values. See the following example:
Existing code:
public class SomeClass {
private static final int LIMIT = 30;
public SomeClass() {
...
}
public void doSomething() {
... //the code that uses LIMIT.
}
}
Add a second constructor that is used by the test:
public class SomeClass {
private static final int DEFAULT_LIMIT = 30;
private final limit
public SomeClass() {
this(DEFAULT_LIMIT);
}
public SomeClass(int limit) {
this.limit = limit;
...
}
public void doSomething() {
... //the code uses limit now.
}
}

how to inject a uiBinder with #Inject (instead of GWT.create())?

Firstly, is doing such thing a good practice ?
I tried what seems to be the right way for me but wasn't successful :
public class FormViewImpl extends CompositeView implements HasUiHandlers<C>, FormView {
public interface SettlementInstructionsSearchFormViewUiBinder extends UiBinder<Widget, SettlementInstructionsSearchFormViewImpl> {}
#Inject
static FormViewImpl uiBinder;
#Inject
static Provider<DateEditorWidget> dateEditorProvider;
#UiField(provided = true)
MyComponent<String> myComp;
#UiField
DateEditorWidget effectiveDateFrom;
// .. other fields
#Inject
public FormViewImpl () {
myComp = new MyComponent<String>("lol");
if (uiBinder == null)
uiBinder = GWT.create(SettlementInstructionsSearchFormViewUiBinder.class);
initWidget(uiBinder.createAndBindUi(this));
}
#UiFactory
DateEditorWidget createDateEditor() {
return dateEditorProvider.get();
}
}
What other things than a class with no arguments is required ? In my company's project the same kind of code works at some other place. Sorry from the high level of noob here...
If you guys had any pointers it would be nice.
Thanks
Two issues:
First, two of your #Inject fields are static - have you done anything to make static fields be injected? Static fields don't get set when Gin (or Guice) creates new instances, those have to be set once and done. As they are static, they will never be garbage collected - this may be okay with you, or it might be a problem, and you should change them to instance fields. If you want to keep them static, then you must invoke requestStaticInjection in your module to ask Gin to initialize them when the ginjector is created.
Next, if you do choose to remove static, the uiBinder field must still be null in that constructor, because the fields can't have been injected yet! How do you set a field on an object that you haven't yet created? That's what you are expecting Gin to be able to do. Instead, consider passing that as an argument into the #Inject decorated constructor. You don't even need to save it as a field, since the widget will only use it the one time.
To have a class generated by GIN (doesn't matter if it is a uiBinder or not) it is not necessary for it to have a default constructor (i.e. the one without parameters). The class you want to inject must have the constructor annotated with #Inject:
#Inject
public InjectMeClass(Object a, Object b)
The other class which is injected, suppose it is a UiBinder, must have the injected fields annotated with #UiField(provided=true):
public class Injected extends Composite {
private static InjectedUiBinder uiBinder = GWT
.create(InjectedUiBinder.class);
interface InjectedUiBinder extends UiBinder<Widget, Injected> {
}
#UiField(provided=true)
InjectMeClass imc;
public Injected(final InjectMeClass imc) {
this.imc=imc;
initWidget(uiBinder.createAndBindUi(this));
}
So, back to your case:
#UiField(provided = true)
MyComponent<String> myComp;
#Inject
public FormViewImpl (MyComponent<String> myComp) {
this.myComp = myComp;
and for example:
public class MyComponent<T> extends Composite {
private T value;
#Inject
public MyComponent(T t) {
this.value = t;
...
}
...
}
In the GIN module you can have a provider:
#Provides
#Singleton
public MyComponent<String> createMyComponent() {
return new MyComponent<String>("lol");
}

Tapestry IoC constructor and injection

I have the following class:
public class MyClass {
#Inject
private MyAnotherClass myAnotherClass;
public MyClass() {
//Perform operations on myAnotherClass.
}
}
I need to do some things in constructor which require an instance of myAnotherClass. Unfortunately myAnotherClass is injected after code in constructor is ran, which means I am performing operations on null...
I could of course instantiate it the classic way (MyAnotherClass myAnotherClass = new MyAnotherClass()) directly in constructor, but I don't think it is the right thing to do in this situation.
What solutions would you suggest to solve this problem?
Best option:
public class MyClass {
private final MyAnotherClass myAnotherClass;
public MyClass(MyAnotherClass other) {
this.myAnotherClass = other;
// And so forth
}
}
T5-IoC will then use constructor injection so there's no need to 'new' up MyClass yourself. See Defining Tapestry IOC Services for more info.
Alternatively:
public class MyClass {
#Inject
private MyAnotherClass myAnotherClass;
#PostInjection
public void setupUsingOther() {
// Called last, after fields are injected
}
}

Testing multiple interface implementations with same tests - JUnit4

I want to run the same JUnit tests for different interface implementations. I found a nice solution with the #Parameter option:
public class InterfaceTest{
MyInterface interface;
public InterfaceTest(MyInterface interface) {
this.interface = interface;
}
#Parameters
public static Collection<Object[]> getParameters()
{
return Arrays.asList(new Object[][] {
{ new GoodInterfaceImpl() },
{ new AnotherInterfaceImpl() }
});
}
}
This test would be run twice, first with the GoodInterfaceImpl then with the AnotherInterfaceImpl class. But the problem is I need for most of the testcases a new object. A simplified example:
#Test
public void isEmptyTest(){
assertTrue(interface.isEmpty());
}
#Test
public void insertTest(){
interface.insert(new Object());
assertFalse(interface.isEmpty());
}
If the isEmptyTest is run after the insertTest it fails.
Is there an option to run automatically each testcase with a new instance of an implementation?
BTW: Implementing a clear() or reset()-method for the interface is not really an options since I would not need it in productive code.
Here is another approach with the Template Method pattern:
The interface-oriented tests go into the base class:
public abstract class MyInterfaceTest {
private MyInterface myInterface;
protected abstract MyInterface makeContractSubject();
#Before
public void setUp() {
myInterface = makeContractSubject();
}
#Test
public void isEmptyTest(){
assertTrue(myInterface.isEmpty());
}
#Test
public void insertTest(){
myInterface.insert(new Object());
assertFalse(myInterface.isEmpty());
}
}
For each concrete class, define a concrete test class:
public class GoodInterfaceImplTest extends MyInterfaceTest {
#Override
protected MyInterface makeContractSubject() {
// initialize new GoodInterfaceImpl
// insert proper stubs
return ...;
}
#Test
public void additionalImplementationSpecificStuff() {
...
}
}
A slight advantage over #Parameter is that you get the name of the concrete test class reported when a test fails, so you know right away which implementation failed.
Btw, in order for this approach to work at all, the interface must be designed in a way which allows testing by the interface methods only. This implies state-based testing -- you cannot verify mocks in the base test class. If you need to verify mocks in implementation-specific tests, these tests must go into the concrete test classes.
Create a factory interface and implementations, possibly only in your test hierarchy if you don't need such a thing in production, and make getParameters() return a list of factories.
Then you can invoke the factory in a #Before annotated method to get a new instance of your actual class under test for each test method run.
Just in case somebody reaches here(like I did), looking for testing multiple implementations of the same interface in .net you could see one of the approaches that I was using in one of the projects here
Below is what we are following in short
The same test project dll is run twice using vstest.console, by setting an environment variable. Inside the test, (either in the assembly initialize or test initialize) register the appropriate implementations into a IoC container, based on the environment variable value.
In Junit 5 you could do:
#ParameterizedTest
#MethodSource("myInterfaceProvider")
void test(MyInterface myInterface) {}
static Stream<MyInterface> myInterfaceProvider() {
return Stream.of(new ImplA(), new ImplB());
}
interface MyInterface {}
static class ImplA implements MyInterface {}
static class ImplB implements MyInterface {}