Assertion error expectation failure EasyMock - junit

I have the next JUnit test, and it works fine, but finally in the verify it throws expectation failure. I think it is because the mocked PsPort is different of the PsPort that I send to the DataReader.
Is there any other way to test it?
#Test
public void testguardarMensaje() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, InstantiationException{
String datoTest = "1=123456";
Constructor<PsPort> constructor = PsPort.class.getDeclaredConstructor(new Class[] {String.class});
constructor.setAccessible(true);
PsPort port = constructor.newInstance("middleware.conf");
PsPort drMock;
int hash1 = datoTest.hashCode();
String hashString1 = String.valueOf(hash1);
String combinedIdDataHashString1 = datoTest +"="+ hashString1;
drMock = strictMock(PsPort.class);
byte[] datoByte = port.encriptarDesencriptarMensaje(combinedIdDataHashString1.getBytes(), Cipher.ENCRYPT_MODE);
drMock.guardarDato(datoByte);
replayAll();
int hash = datoTest.hashCode();
String hashString = String.valueOf(hash);
String combinedIdDataHashString = datoTest +"="+ hashString;
byte[] datoByte2 = port.encriptarDesencriptarMensaje(combinedIdDataHashString.getBytes(), Cipher.ENCRYPT_MODE);
DatagramPacket paquete = new DatagramPacket(datoByte2,datoByte2.length);
paquete.getData();
DataReader dr = new DataReader(port, null, 100, "=", "C:/Users/Asier/Desktop/logs/");
dr.guardarMensaje(paquete, port);
verifyAll();
}

It is really confusing that you have two port objects. What is the sense of creating a mocked drPort; when you are then giving a "real" port object to your class under test?
You see: you either create a mock and pass that down to your code under test (and then you have to setup the mock for the expected behavior; which you can afterwards verify); or you only provide "real" objects to your code under test, but then you would normally do some kind of asserts on the results of calls to "code under test".
So, in that sense, it doesn't really matter that there is at least one problem in your code:
drMock.guardarDato(datoByte);
replayAll();
There should be a call to EasyMock.expectLastCall() after the method invocation on drMock; but as said: as the mocked object isn't really used, that doesn't matter, on the one hand. Because, if you added that statement, your test would always fail; since your un-used mock would never see the calls that you specified it to see.
In order to give you some guidance; this is how you do such kind of testing in general:
SomeClassYouNeed mockedThingy = createStrict/Nice(SomeClassYouNeed.class);
expect(mockedThingy.foo()).andReturn("whatever");
mockedThingy.bar();
expectLastCall();
replay (mockedThingy);
ClassUnderTest underTest = new ClassUnderTest(mockedThingy);
underTest.doSomething();
verify(mockedThingy)
Meaning: any "object" that
a) your "class under test" needs to do its work
b) you want/have to "control" in a certain way
needs to be mocked; including a "specification" of all expected method calls.
Then you provide the mocked things to your code under test; execute the method you want to test ... to finally verify that the mock saw the behavior that you specified for it.

Related

Invalid Use Of Matchers Exception with toString() [duplicate]

I have this TestNG test method code:
#InjectMocks
private FilmeService filmeService = new FilmeServiceImpl();
#Mock
private FilmeDAO filmeDao;
#BeforeMethod(alwaysRun=true)
public void injectDao() {
MockitoAnnotations.initMocks(this);
}
//... another tests here
#Test
public void getRandomEnqueteFilmes() {
#SuppressWarnings("unchecked")
List<Filme> listaFilmes = mock(List.class);
when(listaFilmes.get(anyInt())).thenReturn(any(Filme.class));
when(filmeDao.listAll()).thenReturn(listaFilmes);
List<Filme> filmes = filmeService.getRandomEnqueteFilmes();
assertNotNull(filmes, "Lista de filmes retornou vazia");
assertEquals(filmes.size(), 2, "Lista não retornou com 2 filmes");
}
And I'm getting a "org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
0 matchers expected, 1 recorded:" in the call of listAll() method in this code:
#Override
public List<Filme> getRandomEnqueteFilmes() {
int indice1, indice2 = 0;
List<Filme> filmesExibir = new ArrayList<Filme>();
List<Filme> filmes = dao.listAll();
Random randomGenerator = new Random();
indice1 = randomGenerator.nextInt(5);
do {
indice2 = randomGenerator.nextInt(5);
} while(indice1 == indice2);
filmesExibir.add(filmes.get(indice1));
filmesExibir.add(filmes.get(indice2));
return filmesExibir;
}
I'm prety sure I'm missing something here but I don't know what it is! Someone help?
when(listaFilmes.get(anyInt())).thenReturn(any(Filme.class));
There's your problem. You can't use any in a return value. any is a Matcher—it's used to match parameter values for stubbing and verification—and doesn't make sense in defining a return value for a call. You'll need to explicitly return a Filme instance, or leave it null (which is the default behavior, which would defeat the point of stubbing).
I should note that it's often a good idea to use a real List instead of a mock List. Unlike custom code you've developed, List implementations are well-defined and well-tested, and unlike mock Lists a real List is very unlikely to break if you refactor your system under test to call different methods. It's a matter of style and testing philosophy, but you may find it advantageous just to use a real List here.
Why would the above rule cause that exception? Well, this explanation breaks some of Mockito's abstractions, but matchers don't behave like you think they might—they record a value onto a secret ThreadLocal stack of ArgumentMatcher objects and return null or some other dummy value, and in the call to when or verify Mockito sees a non-empty stack and knows to use those Matchers in preference to actual argument values. As far as Mockito and the Java evaluation order are concerned, your code looks like the following:
when(listaFilmes.get(anyInt())).thenReturn(null);
when(filmeDao.listAll(any())).thenReturn(listaFilmes); // nonsense
Naturally Mockito sees an any matcher, and listAll doesn't take an argument, so there are 0 matchers expected, 1 recorded.

Argument(s) are different! Wanted: Actual invocation has different arguments:

ServiceClass:
public void createManualEvaluationReductionChangeHistory(Long key, String accountId, RegisterReductionPerFunction registerReductionPerFunction, String languageCode, String comments, String pagRedFlag) {
ProfessionalCustomerHistory professionalCustomerHistory = new ProfessionalCustomerHistory();
professionalCustomerHistory.setDescription(comments);
professionalCustomerHistory.setReductionCategory(registerReductionPerFunction.getReductionCategoryCode());
professionalCustomerHistory.setReductionType(registerReductionPerFunction.getReductionTypeCode());
professionalCustomerHistory.setValidityId(registerReductionPerFunction.getValidityId().longValue());
professionalCustomerHistory.setReductionPercentage(reductionCategoryService.getReductionPercentage(languageCode,
registerReductionPerFunction.getReductionCategoryCode(), registerReductionPerFunction.getReductionTypeCode()));
professionalCustomerHistory.setTotalReduction(professionalCustomerHistory.getReductionPercentage());
professionalCustomerHistory.setPagFixedReductionFlag(pagRedFlag);
setCommonHistoryDetails(professionalCustomerHistory, Constants.NO, accountId, key, Constants.HISTORY_TYPE_REDUCTIONS);
professionalCustomerHistoryDlService.create(professionalCustomerHistory);
}
Junit Test:
#Test
public void createManualEvaluationReductionChangeHistory() {
ProfessionalCustomerHistory professionalCustomerHistory = new ProfessionalCustomerHistory();
RegisterReductionPerFunction registerReductionPerFunction = new RegisterReductionPerFunction();
professionalCustomerHistory.setValidityId(1L);
registerReductionPerFunction.setValidityId(1);
professionalCustomerHistory.setProfCustomerId(PROF_CUST_ID);
professionalCustomerHistory.setHistoryType("RD");
professionalCustomerHistory.setEditedBy(ACCOUNT_ID);
professionalCustomerHistory.setHistoryDate(new Date());
professionalCustomerHistory.setNoDeleteFlag("N");
professionalCustomerHistory.setReductionPercentage(null);
professionalCustomerHistory.setTotalReduction(null);
professionalCustomerHistory.setDescription(COMMENTS);
Mockito.when(reductionCategoryService.getReductionPercentage(LANGUAGE_CODE, null, null)).thenReturn(null);
profCustomerHistoryService.createManualEvaluationReductionChangeHistory(PROF_CUST_ID, ACCOUNT_ID.toString(), registerReductionPerFunction, LANGUAGE_CODE, COMMENTS, null);
Mockito.verify(reductionCategoryService).getReductionPercentage(LANGUAGE_CODE,null,null);
Mockito.verify(professionalCustomerHistoryDlService).create(professionalCustomerHistory);
}
When i am testing it getting below error.
Argument(s) are different! Wanted:
Actual invocation has different arguments:
But i see all the parameters are exact the same. what might be causing the issue?
ProfessionalCustomerHistory is a DB entity, i dont have equals and hashcode
Assuming that its only your 2nd verify that fails, this is the problem.
Currently you create a different ProfessionalCustomerHistory object in your test and in your logic. They might have the same content but without properly implemented equals and hashcode methods, the default implementation in java only cares about the object reference.
If you use an IDE it probably has some generate method that lets you generate the proper equals and hashCode methods.
If you only want to validate that the correct method is called, without caring about the exact content, you could use:
Mockito.verify(professionalCustomerHistoryDlService)
.create(Mockito.any(ProfessionalCustomerHistory.class));
If you can not or do not want to change the ProfessionalCustomerHistory class, you could use an ArgumentCaptor and compare the distinct fields afterwards.

Unable to mock URL class using PowerMockito/Mockito

I am trying to use PowerMockito to mock the creation of the java.net.URL class in my code that I'm testing. Basically, I want to prevent the real HTTP request from occurring and instead 1) check the data when the request is made and 2) supply my own test data back on a mocked response. This is what I'm trying:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ URL.class, MockedHttpConnection.class })
public class Test {
URL mockedURL = PowerMockito.mock(URL.class);
MockedHttpConnection mockedConnection = PowerMockito.mock(MockedHttpConnection.class);
...
PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL);
PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection);
...
}
The code that I want to test looks like this:
URL wlInvokeUrl = new URL(wlInvokeUrlString);
connection = (HttpURLConnection) wlInvokeUrl.openConnection();
Earlier in my test scenario I mock the wlInvokeUrlString to match "MyURLString". I've also tried using various other forms of the whenNew line, trying to inject the mock. No matter what I try, it never intercepts the constructor. All I want to do is "catch" the call to openConnection() and have it return my mocked HTTP connection instead of the real one.
I have mocked other classes ahead of this one in the same script and these are working as expected. Either I need a second pair of eyes (probably true) or there is something unique about the URL class. I did notice that if I use "whenNew(URL.class).withAnyArguments()" and change the "thenReturn" to "thenAnswer" I could get it to trigger. Only problem is I never get the URL call for my code. What I see is an invocation of the 3-argument constructor for URL.class with all nulls for the parameters. Could it be this class is from the Java runtime and is bootstrapped by the test runner? Any help is much appreciated.
It's a common mistake when use PowerMockito.whenNew.
Note that you must prepare the class creating the new instance of MyClass for test, not the MyClass itself. E.g. if the class doing new MyClass() is called X then you'd have to do #PrepareForTest(X.class) in order for whenNew to work
From Powermock wiki
So, you need a bit change your test and add to #PrepareForTesta class which create a new instance of URLlike:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ URL.class, MockedHttpConnection.class , ConnectionUser.class})
public class URLTest {
public class URLTest {
private ConnectionUser connectionUser;
#Before
public void setUp() throws Exception {
connectionUser = new ConnectionUser();
}
#Test
public void testName() throws Exception {
URL mockedURL = PowerMockito.mock(URL.class);
MockedHttpConnection mockedConnection = PowerMockito.mock(MockedHttpConnection.class);
PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL);
PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection);
connectionUser.open();
assertEquals(mockedConnection, connectionUser.getConnection());
}
}
where:
public class ConnectionUser {
private String wlInvokeUrlString = "MyURLString";
private HttpURLConnection connection;
public void open() throws IOException {
URL wlInvokeUrl = new URL(wlInvokeUrlString);
connection = (HttpURLConnection) wlInvokeUrl.openConnection();
}
public HttpURLConnection getConnection() {
return connection;
}
}
I'm not sure the difference between .withParameterTypes(x) and .withArguments(x) but I believe you need to set it up as follows for your code to work. Give it a try and let me know if this doesn't help.
PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection);
PowerMockito.whenNew(URL.class).withArguments(Mockito.anyString()).thenReturn(mockedURL);
The problem is that the arguments of the real call are not matching with the expected in your mock.
PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL) will return mockedURL only the call is new URL("MyURLString").
If you change it to:
PowerMockito.whenNew( URL.class ).withParameterTypes( String.class )
.withArguments( org.mockito.Matchers.any( String.class ) ).thenReturn( mockedURL );
It will catch any string passed to the constructor URL(String) (even null) and return your mock.
When you tried
"whenNew(URL.class).withAnyArguments()" and change the "thenReturn" to
"thenAnswer" I could get it to trigger. Only problem is I never get
the URL call for my code. What I see is an invocation of the
3-argument constructor for URL.class with all nulls for the
parameters.
PowerMock will try to mock all constructors (org.powermock.api.mockito.internal.expectation.DelegatingToConstructorsOngoingStubbing.InvokeStubMethod at line 122) then it calls the first one (with 3 arguments) and mock its answer. But the subsequent calls will return the already mocked one because you told it to mock for any arguments. That's why you see just one call with null, null, null in your Answer.

Struts2 TDD - Testing chaining - how to prevent dispatcher from doing the chain?

I'm running a JUnit test - testing an action that chains.
We have a large internal testing framework (inherits from StrutsTestCase) that sets up everything for an action to work during a test but when chaining to a new action - the new (chained) action isn't setup correct and internal code runs into NULLs.
I believe the test should only test for the correct result from the action call and should not test the chained action.
My Q: I'm looking for a way to disable chaining while testing. Can the Dispatcher created in StrutsTestCase.setUp() be configured to handle chaining differently (eg. do nothing)?
Wish I could avoid chaining but that's the way it's done here.
EDIT - Here is code:
Action:
#Action(value = SUBMIT, results = {
#Result(name = SUCCESS, type = "chain", params = { "actionName", "myActionName", "namespace", "/myNameSpace" }) })
public String submitForm() throws IllegalAccessException, InvocationTargetException, IOException {
return SUCCESS;
}
Test:
#Test
public void testStuff() throws Exception {
setupAction();
prepareForValidUser();
this.actionUnderTest.getModel().setUpSomeStuff(someSetupValue);
final String result = this.proxy.execute();
assertEquals("Result not the expected result", SUCCESS, result);
}
The test relies heavily on a nice testing framework; proxy.execute() is what runs the action (com.opensymphony.xwork2.ActionProxy.class).
The solution is to simply call the action method directly instead of relying on the struts framework to execute the action for you.
This:
final String result = this.proxy.execute();
becomes
final String result = this.actionUnderTest.myActionMethod();
This worked well for me! Doing this meant that nothing handled/executed on the result of the action method (eg. no chaining occurred).

How to mock a method in PowerMock?

I'm using PowerMock 1.4.12 and JUnit 4.8.1. I'm having a problem getting a method to return the data I want it to. I have
#Before
public void setUp() throws Exception
{
...
userService = createMock(UserService.class);
loginController.setUserService(userService);
…
}
#Test
public final void testAuthenticateForLoggedInAdmin()
{
authorities.add(adminAuthority);
final User user = new User();
user.setUserName("userName");
user.setPassword("password");
user.setFirstName("firstName");
user.setMiddleName("middleName");
user.setLastName("lastName");
user.setUrl("localhost");
user.setId("id1");
final TestsubcoAuthenticationUser principal = new TestsubcoAuthenticationUser(user.getUserName(),
user.getPassword(),
true,
true,
true,
true,
authorities,
user.getFirstName(),
user.getLastName(),
user.getMiddleName(),
user.getUrl(),
user.getId(),
null,
null,
null);
authentication = new UsernamePasswordAuthenticationToken(principal, new Object(), authorities);
securityContext.setAuthentication(authentication);
mockStatic(SecurityContextHolder.class);
expect(SecurityContextHolder.getContext()).andReturn(securityContext);
expect(userService.findByUsernameAndUrl(user.getUserName(), user.getUrl())).andReturn(user);
...
String result = loginController.authenticate();
but when my method in question gets called from within the controller,
final User user = userService.findByUsernameAndUrl(sbUser.getUsername(), sbUser.getUrl());
the return value is null instead of the object I specified. Any theories behind why this is or suggestions for troubleshooting further? I have verified through debugging that the String parameter values passed in the controller are the same as what I specify in the "expect" method.
It looks like you did not call replay on your mocks.
replay
but when my method in question gets called from within the controller,
I am not sure what your mean, method in question gets called from within the controller.
When you call the method ,your userService object should be the same object which you mocked. also check the argument value if same.
I you dont find this usefull, share more detail in what your trying to unit test here.