i have a private boolean field that im trying to set to true by setting its internal state using power mockito or by using the private setter but neither are working. i put print statements in the logic to check the variable. i see that it is being set to true in my beforeclass but once the test hits a statement using the private field, its false. could someone please explain what im doing wrong?
SQLJConnectionBase spy = PowerMockito.spy( new SQLJConnectionBase());
System.out.println("current internal state - " + Whitebox.getInternalState(spy, "isJUnitTestCase"));
PowerMockito.doReturn(true).when(spy, "isJUnitTestCase");
Whitebox.setInternalState(spy, "isJUnitTestCase", true);
System.out.println("new internal state - " + Whitebox.getInternalState(spy, "isJUnitTestCase"));
console output of the print statements in the test class before and after the manipulation of the private field in the beforeclass method
current internal state - false
new internal state - true
console output of the print statements in the class being tested in the method using the private method and private variable
variable state - false
method call variable state - false
as you can see, isJUnitTest is being set to true in the beforeclass, but when the test case actually uses it, isJUnitTest is false.
These are my annotations on the test class
#PowerMockIgnore("javax.management.*")
#RunWith(PowerMockRunner.class)
#PrepareForTest({SQLJConnectionBase.class})
any ideas?
Is isJUnitTestCase actually a field name? It appears that you may possibly be specifying the setter method name, but you would need to give the field name for whatever field the isJUnitTestCase method sets.
See https://github.com/powermock/powermock/wiki/Bypass-Encapsulation for an example.
But if you are adding a member to the class you are testing that indicates if this is a unit test of not, you are doing something wrong in your class. You shouldn't add test crud to a real class--there are other approaches to allow you to test your code without having to add such hooks.
Related
I'm using Mockito 1.9.0. I want mock the behaviour for a single method of a class in a JUnit test, so I have
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
The problem is, in the second line, myClassSpy.method1() is actually getting called, resulting in an exception. The only reason I'm using mocks is so that later, whenever myClassSpy.method1() is called, the real method won't be called and the myResults object will be returned.
MyClass is an interface and myInstance is an implementation of that, if that matters.
What do I need to do to correct this spying behaviour?
Let me quote the official documentation:
Important gotcha on spying real objects!
Sometimes it's impossible to use when(Object) for stubbing spies. Example:
List list = new LinkedList();
List spy = spy(list);
// Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
// You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
In your case it goes something like:
doReturn(resultsIWant).when(myClassSpy).method1();
In my case, using Mockito 2.0, I had to change all the any() parameters to nullable() in order to stub the real call.
My case was different from the accepted answer. I was trying to mock a package-private method for an instance that did not live in that package
package common;
public class AnimalĀ {
void packageProtected();
}
package instances;
class Dog extends Animal { }
and the test classes
package common;
public abstract class AnimalTest<T extends Animal> {
#Before
setup(){
doNothing().when(getInstance()).packageProtected();
}
abstract T getInstance();
}
package instances;
class DogTest extends AnimalTest<Dog> {
Dog getInstance(){
return spy(new Dog());
}
#Test
public void myTest(){}
}
The compilation is correct, but when it tries to setup the test, it invokes the real method instead.
Declaring the method protected or public fixes the issue, tho it's not a clean solution.
The answer by Tomasz Nurkiewicz appears not to tell the whole story!
NB Mockito version: 1.10.19.
I am very much a Mockito newb, so can't explain the following behaviour: if there's an expert out there who can improve this answer, please feel free.
The method in question here, getContentStringValue, is NOT final and NOT static.
This line does call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), isA( ScoreDoc.class ));
This line does not call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), any( ScoreDoc.class ));
For reasons which I can't answer, using isA() causes the intended (?) "do not call method" behaviour of doReturn to fail.
Let's look at the method signatures involved here: they are both static methods of Matchers. Both are said by the Javadoc to return null, which is a little difficult to get your head around in itself. Presumably the Class object passed as the parameter is examined but the result either never calculated or discarded. Given that null can stand for any class and that you are hoping for the mocked method not to be called, couldn't the signatures of isA( ... ) and any( ... ) just return null rather than a generic parameter* <T>?
Anyway:
public static <T> T isA(java.lang.Class<T> clazz)
public static <T> T any(java.lang.Class<T> clazz)
The API documentation does not give any clue about this. It also seems to say the need for such "do not call method" behaviour is "very rare". Personally I use this technique all the time: typically I find that mocking involves a few lines which "set the scene" ... followed by calling a method which then "plays out" the scene in the mock context which you have staged... and while you are setting up the scenery and the props the last thing you want is for the actors to enter stage left and start acting their hearts out...
But this is way beyond my pay grade... I invite explanations from any passing Mockito high priests...
* is "generic parameter" the right term?
One more possible scenario which may causing issues with spies is when you're testing spring beans (with spring test framework) or some other framework that is proxing your objects during test.
Example
#Autowired
private MonitoringDocumentsRepository repository
void test(){
repository = Mockito.spy(repository)
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
In above code both Spring and Mockito will try to proxy your MonitoringDocumentsRepository object, but Spring will be first, which will cause real call of findMonitoringDocuments method. If we debug our code just after putting a spy on repository object it will look like this inside debugger:
repository = MonitoringDocumentsRepository$$EnhancerBySpringCGLIB$$MockitoMock$
#SpyBean to the rescue
If instead #Autowired annotation we use #SpyBean annotation, we will solve above problem, the SpyBean annotation will also inject repository object but it will be firstly proxied by Mockito and will look like this inside debugger
repository = MonitoringDocumentsRepository$$MockitoMock$$EnhancerBySpringCGLIB$
and here is the code:
#SpyBean
private MonitoringDocumentsRepository repository
void test(){
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
Important gotcha on spying real objects
When stubbing a method using spies , please use doReturn() family of methods.
when(Object) would result in calling the actual method that can throw exceptions.
List spy = spy(new LinkedList());
//Incorrect , spy.get() will throw IndexOutOfBoundsException
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
I've found yet another reason for spy to call the original method.
Someone had the idea to mock a final class, and found about MockMaker:
As this works differently to our current mechanism and this one has different limitations and as we want to gather experience and user feedback, this feature had to be explicitly activated to be available ; it can be done via the mockito extension mechanism by creating the file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker containing a single line: mock-maker-inline
Source: https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
After I merged and brought that file to my machine, my tests failed.
I just had to remove the line (or the file), and spy() worked.
One way to make sure a method from a class is not called is to override the method with a dummy.
WebFormCreatorActivity activity = spy(new WebFormCreatorActivity(clientFactory) {//spy(new WebFormCreatorActivity(clientFactory));
#Override
public void select(TreeItem i) {
log.debug("SELECT");
};
});
As mentioned in some of the comments, my method was "static" (though being called on by an instance of the class)
public class A {
static void myMethod() {...}
}
A instance = spy(new A());
verify(instance).myMethod(); // still calls the original method because it's static
Work around was make an instance method or upgrade Mockito to a newer version with some config: https://stackoverflow.com/a/62860455/32453
Bit late to the party but above solutions did not work for me , so sharing my 0.02$
Mokcito version: 1.10.19
MyClass.java
private int handleAction(List<String> argList, String action)
Test.java
MyClass spy = PowerMockito.spy(new MyClass());
Following did NOT work for me (actual method was being called):
1.
doReturn(0).when(spy , "handleAction", ListUtils.EMPTY_LIST, new String());
2.
doReturn(0).when(spy , "handleAction", any(), anyString());
3.
doReturn(0).when(spy , "handleAction", null, null);
Following WORKED:
doReturn(0).when(spy , "handleAction", any(List.class), anyString());
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.
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.
Im reading the tutorials here: http://www.adobe.com/devnet/actionscript/learning/oop-concepts/objects-and-classes.html and an on the second paragraph of the Dot Notation section. It uses the 'Sprite' class in ActionScript 3. The tutorial created an instance of the Sprite class and called it myFirstObject. It says..
"Then, using that reference variable and dot notation, values are assigned to the x and visible properties of the instance, and the methods startDrag and stopDrag are called."
I noticed that there are no () after a property. For example:
myFirstObject.x = 300;
compared to a method
myFirstObject.startDrag();
So, what's the difference between a property and method of an instance? I think it would help if I can see the Sprite class but I wasn't able to find it when I tried google'ing.
A property has a Get() and Set() method that allow you to use the same call to get or assign a value. When you assign the property a value, you are calling the Set method. When you retrieve a value, you are using the Get method. Properties automatically call the appropriate Get or Set method based on the operation.
To help you visualize the setup, here is a sample property (VB.Net):
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Private Set(ByVal value As String)
_name = value
End Set
End Property
To call it, you would use:
MyObject.Name = "Test" <- Sets the name to test
MsgBox("The name is: " & MyObject.Name) <- Gets the value of name
Although the example is in VB.Net, the theory is still the same.
A method, on the other hand, would be the equivalent of either the Get or Set routines. As a method, you have to call it and supply the parameters inside of the parenthesis. Even if it has none, you still need the (). When you want to update a variable, you have to pass values to the method instead of setting it equal to the value.
Here is a similar example:
Private _name As String
Public Function Name(Optional ByVal strName as String = "") as String
If strName <> "" then
_name = strName
End If
Return _name
End Function
Here is a similar example of how to use it:
MyObject.Name("Test") <- Sets the name to test
MsgBox("The name is: " & MyObject.Name()) <- Gets the value of name
Properties and methods are similar in that both are implemented as procedures that accept arguments. In general, properties store data for an object, and methods are actions an object can be asked to perform.
I have a service class which has overloaded constructors. One constructor has 5 parameters and the other has 4.
Before I call,
var service = IoC.Resolve<IService>();
I want to do a test and based on the result of this test, resolve service using a specific constructor. In other words,
bool testPassed = CheckCertainConditions();
if (testPassed)
{
//Resolve service using 5 paramater constructor
}
else
{
//Resolve service using 4 parameter constructor
//If I use 5 parameter constructor under these conditions I will have epic fail.
}
Is there a way I can specify which one I want to use?
In general, you should watch out for ambiguity in constructors when it comes to DI because you are essentially saying to any caller that 'I don't really care if you use one or the other'. This is unlikely to be what you intended.
However, one container-agnostic solution is to wrap the conditional implementation into another class that implements the same interface:
public class ConditionalService : IService
{
private readonly IService service;
public ConditionalService()
{
bool testPassed = CheckCertainConditions();
if (testPassed)
{
// assign this.service using 5 paramater constructor
}
else
{
// assign this.service using 4 parameter constructor
}
}
// assuming that IService has a Foo method:
public IBaz Foo(IBar bar)
{
return this.service.Foo(bar);
}
}
If you can't perform the CheckCertainConditions check in the constructor, you can use lazy evaluation instead.
It would be a good idea to let ConditionalService request all dependencies via Constructor Injection, but I left that out of the example code.
You can register ConditionalService with the DI Container instead of the real implementation.
My underlying problem was that I was trying to resolve my class which had the following signature:
public DatabaseSchemaSynchronisationService(IDatabaseService databaseService, IUserSessionManager userSessionManager)
This was basically useless to me because my usersessionmanager had no active NHibernate.ISession because a connection to my database had not yet been made. What I was trying to do was check if I did have a connection and only then resolve this class which served as a service to run database update scripts.
When changing my whole class to perform the scripts in a different way, all I needed in its constructor's signature was:
public DatabaseSchemaSynchronisationService(ISessionFactory sessionFactory)
This allowed me to open my own session. I did, however have to first check if the connection was ready before attempting to resolve the class, but having IDatabaseSchemaSynchronisationService as a parameter to another class's constructor; this class also gettting resolved somewhere where I could not check the db connection was a bad idea.
Instead in this second class, I took the IDatabaseSchemaSynchronisationService paramater out of the constructor signature and made it a local variable which only gets instantiated (resolved) :
if (connectionIsReady)
Thanks to everyone who answered.