Mocking a method within a class using Mockito spy - java

Refering to mock methods in same class
class Temp() {
public boolean methodA(String param) {
try {
if(methodB(param))
return true;
return false;
} catch (Exception e) {
e.printStackTrace();
}
}
}
The test class
#Test
public void testMethodA() {
Temp temp = new Temp();
Temp spyTemp = Mockito.spy(temp);
Mockito.doReturn(true).when(spyTemp).methodB(Mockito.any());
boolean status = temp.methodA("XYZ");
Assert.assertEquals(true, status);
}
When calling the real class temp to methodA should return the mocked method B value. Thus returning true. Why is this incorrect. I encounter the same problem.
I want to run the test on the real class and not for mock object as suggested by the answer. I want to run the class methodA and expect the mocked object spyTemp methodB value when it is called

Here is the Problem: methodA() you´re callint is from temp and you´ve defined a returning value from tempSPY.
So you need to call tempSpy.methodA() and then it´s returning the value of methodB() you´ve defined.
Here the solution if methodB() is public - spy temp/cut and call it this way:
// temp = cut
#Test
public void testMethodA_valid() {
// given
Temp spyTemp = Mockito.spy(temp);
boolean expected = true;
Mockito.doReturn(expected).when(spyTemp).methodB(Mockito.any(String.class));
// when
boolean actual = spyTemp.methodA("XYZ");
// then (faster readable)
Mockito.verify(spyTemp, times(1)).methodB(any(String.class))
Mockito.verifyNoMoreInteraction(<ALL YOUR MOCKS HERE>);
Assert.assertEquals(expected, is(equalTo(actual)));
}
If methodB() is private you can´t define what it should return. Then is´t just this and if error occures then methodB() got wrong behaviour:
#Test
public void testMethodA_valid() {
// given
boolean expected = true;
// when
boolean actual = temp.methodA("XYZ");
// then (faster readable)
Assert.assertEquals(expected, is(equalTo(actual)));
}

Related

Mockito ArgumentCaptor does not return any values on verification

I am trying to use argument capture to determine what arguments are being passed to a mocked Mockito method, but I am not able to capture any values.
class CombinedEvent
{
final List<String> events;
public CombinedEvent() {
this.events = new ArrayList<>();
this.events.add("WATCHITM");
this.events.add("BIDITEM");
}
}
Holder class
class CombinedNotificationAdapter {
private CombinedEvent combinedEvent;
CombinedNotificationAdapter() {
this.combinedEvent = new CombinedEvent();
}
public boolean isEnabled(String user, NotificationPreferenceManager preferenceManager) {
boolean status = true;
for (String event : combinedEvent.events) {
status = status && preferenceManager.isEventEnabled(user, event);
}
return status;
}
}
My unit test
#RunWith(JUnit4.class)
class CombinedNotificationAdapterTest {
private CombinedNotificationAdapter adapter;
#Mock
private NotificationPreferenceManager preferenceManager;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
adapter = new CombinedNotificationAdapter();
}
#Test
public void testIsEnabled() {
doReturn(true).when(preferenceManager).isEventEnabled(eq("test"), anyString());
Assert.assertTrue(adapter.isEnabled("test", preferenceManager));
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(preferenceManager, times(2)).isEventEnabled(eq("test"), captor.capture());
System.out.println(captor.getAllValues());
}
}
The output of captor.getAllValues() is an empty list. I would like the values to return a list of WATCHITM and BIDITEM. I don't know what I am going wrong.
Reference:
https://static.javadoc.io/org.mockito/mockito-core/2.28.2/org/mockito/Mockito.html#15
https://static.javadoc.io/org.mockito/mockito-core/2.6.9/org/mockito/ArgumentCaptor.html
I think you are overdoing:
doReturn(true)
. when(preferenceManager)
.isEventEnabled(eq("test"), anyString()):
You are scrubbing that expected method invocation and then combining that with your argument captor. And that does not work. You can either stub or capture, not both things! See this existing question for example.
My suggestion: look at this answer and learn how to create your own Answer object. Those get passed an instance of InvocationOnMock. And that class allows you to check the arguments passed into the mocked calls, too!

Junit Test Bool Value

Hello Every One I Have This Method Which it Checks if the Input String Is Numbers only And Its Return True Or False
I Want To Make A Junit Test For this method and Actually I Don't know how to test Method Like This Can Any One Help And Thank You All.
My Method:
private Boolean Check_Ean(String EAN_Ch)
{
Long EAN;
try
{
EAN = Long.parseLong(EAN_Ch);
return true;
}
catch (NumberFormatException e)
{
return false;
}
}
First you need to create a class in the test folder(located at the same path as main). Then you need to use their annotations to or either Prepare the information, Test and Destroy the information(usefull when you have DB connection opens or streams):
public class TestClass {
#Before
public void setup() {
//prepare information
}
#Test
public void testCheck_Ean() {
boolean result = Check_Ean(...);
Assert.assertTrue(result);
}
#After
public void destroy() {
//if you need to "destroy" some info
}
}
tester = new CLASS_NAME();
assertTrue(tester.Check_Ean("5");
assertFalse(tester.Check_Ean("this is noot a Long");
You might be overthinking it. Also the Check_Ean method maybe could be static if you pass the Ean as a parameter rather than getting a class variable.

How to mock different responses from constructor with PowerMock

I'm getting an error from PowerMock when running the following:
whenNew(Socket.class).withAnyArguments().thenReturn(server).thenCallRealMethod();
The error is:
You probably stored a reference to OngoingStubbing returned by when() and
called stubbing methods like thenReturn() on this reference more than once.
Examples of correct usage:
when(mock.isOk()).thenReturn(true).thenReturn(false).thenThrow(exception);
when(mock.isOk()).thenReturn(true, false).thenThrow(exception);
Any idea how I can return my mock object on the first new and afterwards call the default constructor?
I don't know about any built-in solution, but try this one, it's supposed to work:
whenNew(Socket.class).withAnyArguments().thenAnswer(new Answer<Object>() {
boolean firstCall;
#Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
if (firstCall) {
firstCall = false;
return server;
}
return invocationOnMock.callRealMethod();
}
});
With thenAnswer you can implement any logic for mocking a method inside an Answer.
So, if you need such a behavior often, I would suggest you encapsulating it into a class like this:
class MockOnlyFirstCall<T> implements Answer<T> {
private final T firstCallResult;
private boolean firstCall = true;
public MockOnlyFirstCall(T firstCallResult) {
this.firstCallResult = firstCallResult;
}
#Override
public T answer(InvocationOnMock invocationOnMock) throws Throwable {
if (firstCall) {
firstCall = false;
return firstCallResult;
}
return invocationOnMock.callRealMethod();
}
}
Then you could just do
whenNew(Socket.class)
.withAnyArguments()
.thenAnswer(new MockOnlyFirstCall<>(server));

How do I mock a method with void return type in JMockit?

I'm using TestNG and JMockit for testing. My code goes like this:
public boolean testMethod(String a, String b) {
//processing .....
mockClass.mockMethod(a);
//processing....
}
The mockMethod():
Class MockClass {
public void mockMethod(String a) {
//some operations to mock
}
}
I'm using MockUp according to this question: (How to mock public void method using jmockit?)
I'm still getting the NPE. What am I doing wrong? Also, is it because I'm using it like this?
#Test
public void test() {
new Expectations() {
{
//for statements preceding mockMethod()....
new MockUp<MockClass>(){
#Mock
public void mockMethod(String a) {
//do nothing
}
};
}
};
}
I've put it outside Expectations() & used NonStrictExpectations too. How do I fix this?
If the method to be mocked is not returning anything, you don't need to do anything special in expectations. You can define your class to be mocked using #Injectable or #Mocked annotations in usual way. Optionally you can add an expectation to verify the number of times the method is called. Also you can add verification step to capture the argument "a" and do assertions on that. Refer below code sample.
#Tested
private MyClassToBeTested myClassToBeTested;
#Injectable
private MockClass mockClass;
#Test
public void test() {
// Add required expectations
new Expectations() {{
...
..
}};
// Invoke the method to be tested with test values;
String expectedA = "testValueA";
String expectedB = "testValueB";
boolean result = myClassToBeTested.testMethod(expectedA, expectedB);
// Assert the return value of the method
Assert.assertTrue(result);
// Do the verifications and assertions
new Verifications() {{
String actualA;
mockClass.mockMethod(actualA = withCapture()); times = 1;
Assert.assertNotNull("Should not be null", actualA);
Assert.assertEquals(actualA, expectedA);
...
..
}};
}
For void method mocking You can make Expectations without any result as shown below :
#Tested
private MyClassToBeTested myClassToBeTested;
#Injectable
private MockClass mockClass;
#Test
public void test() {
new Expectations() {{
mockClass.mockMethod(anyString);
}};
String inputA = "testValueA";
String inputB = "testValueB";
boolean result = myClassToBeTested.testMethod(inputA, inputB);
assertEquals(true, result);
}

Check if a method was called inside another method

Is there any way in java to check if a certain method was called inside another method? I am testing a class and the method I am having trouble with plays sound and there is virtually no way of getting the audio file that is played(private attribute inside an inner class) without changing the code. However the way the method plays sounds is it calls a method that plays a single sound (playSadMusic, playHappyMusic, etc). Those methods are in an interface that I have to create a mock object for. I'm a little stuck on how I would exactly go about testing this. Any thoughts? Any other ideas on how I could possibly test this other than check if a certain method was call are welcome.
I am using JMock 2.6.0 and JUnit 4
the audio inteface
public interface StockTickerAudioInterface {
public abstract void playHappyMusic();
public abstract void playSadMusic();
public abstract void playErrorMusic();
}
anther interface I have to create a mock for
public interface StockQuoteGeneratorInterface {
public abstract StockQuoteInterface getCurrentQuote() throws Exception;
public abstract String getSymbol();
public abstract void setSymbol(String symbol);
public abstract StockQuoteGeneratorInterface createNewInstance(String symbol);
}
the class being tested
public class StockQuoteAnalyzer {
private StockTickerAudioInterface audioPlayer = null;
private String symbol;
private StockQuoteGeneratorInterface stockQuoteSource = null;
private StockQuoteInterface lastQuote = null;
private StockQuoteInterface currentQuote = null;
public StockQuoteAnalyzer(String symbol,
StockQuoteGeneratorInterface stockQuoteSource,
StockTickerAudioInterface audioPlayer)
throws InvalidStockSymbolException, NullPointerException,
StockTickerConnectionError {
super();
// Check the validity of the symbol.
if (StockTickerListing.getSingleton().isValidTickerSymbol(symbol) == true){
this.symbol = symbol;
} else {
throw new InvalidStockSymbolException("Symbol " + symbol
+ "not found.");
}
if (stockQuoteSource == null) {
throw new NullPointerException(
"The source for stock quotes can not be null");
}
this.stockQuoteSource = stockQuoteSource;
this.audioPlayer = audioPlayer;
}
public double getChangeSinceLast() {
double retVal = 0.0;
if (this.lastQuote != null) {
double delta = this.currentQuote.getLastTrade() - this.lastQuote.getLastTrade();
retVal = 100 * (delta / this.lastQuote.getLastTrade());
}
return retVal;
}
public double getChangeSinceYesterday() {
double delta = (this.currentQuote.getLastTrade() - this.currentQuote
.getClose());
return 100 * (delta / this.currentQuote.getClose());
}
public void playAppropriateAudio() {
if ((this.getChangeSinceYesterday() > 2)
|| (this.getChangeSinceLast() > 0.5)) {
audioPlayer.playHappyMusic();
}
if ((this.getChangeSinceYesterday() < -2)
|| (this.getChangeSinceLast() < -0.5)) {
audioPlayer.playSadMusic();
}
}
}
If you use Mockito you can use verify() to check the number of times a method was called. Use it like this:
verify(mockedObject, times(1)).methodToValidate();
You can check if methodToValidate() was called with a specific string, e.i verify(mockedObject, times(1)).methodToValidate("a specific value"); or you can use it with anyString() like this: verify(mockedObject, times(1)).methodToValidate(anyString());.
Unless this method is called with your specified paramterer, the test will fail
Read more about verify here.
UPDATE
Since your edited post states that you are using jMock, a quick googeling showed me that it is possible to achieve a similar behaviour with jMock and it's expect method. It's used as below:
mockedObject.expects(once()).method("nameOfMethod").with( eq("An optional paramter") );
More detailed explanation can be found by reading jMocks getting started page.
say you have a method child() which is called in parent()
public void parent() {
child();
}
In child() to get the last method it got invoked from, you can use StackTraceElement
public void child() {
StackTraceElement[] traces = Thread.currentThread().getStackTrace();
boolean check = false;
for(StackTraceElement element : traces) {
if(check) {
System.out.println("Calling method - " + element.getMethodName());
}
if(element.getMethodName().equals("child")) {
check = true;
}
}
}
If you are writing a mock object with the methods you want to check whether they were called, you can implement the methods in a way they raise some flag when they are called, for example
public void playHappyMusic() {
this.wasCalled = true;
}
wasCalled being a public (or with getters) class variable. Then you just check the flag.
Provide you are in the same thread as the calling method, you can check the stack trace in any given moment this way:
Thread.currentThread().getStackTrace()
You can see what method are called doing it like this:
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
System.out.println(ste);
}
For example:
public class Test {
public static void main (String[]s){
Test test = new Test();
test.makeTest();
}
public void makeTest(){
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
System.out.println(ste);
}
}
results in
java.lang.Thread.getStackTrace(Unknown Source)
Test.makeTest(Test.java:17)
Test.main(Test.java:11)

Categories

Resources