I have a static method which will be invoking from test method in a class as bellow
public class MyClass
{
private static boolean mockMethod( String input )
{
boolean value;
//do something to value
return value;
}
public static boolean methodToTest()
{
boolean getVal = mockMethod( "input" );
//do something to getVal
return getVal;
}
}
I want to write a test case for method methodToTest by mocking mockMethod.
Tried as bellow and it doesn't give any output
#Before
public void init()
{
Mockit.setUpMock( MyClass.class, MyClassMocked.class );
}
public static class MyClassMocked extends MockUp<MyClass>
{
#Mock
private static boolean mockMethod( String input )
{
return true;
}
}
#Test
public void testMethodToTest()
{
assertTrue( ( MyClass.methodToTest() );
}
To mock your static method:
new MockUp<MyClass>()
{
#Mock
boolean mockMethod( String input ) // no access modifier required
{
return true;
}
};
To mock the static private method:
#Mocked({"mockMethod"})
MyClass myClass;
String result;
#Before
public void init()
{
new Expectations(myClass)
{
{
invoke(MyClass.class, "mockMethod", anyString);
returns(result);
}
}
}
#Test
public void testMethodToTest()
{
result = "true"; // Replace result with what you want to test...
assertTrue( ( MyClass.methodToTest() );
}
From JavaDoc:
Object mockit.Invocations.invoke(Class methodOwner, String methodName, Object... methodArgs)
Specifies an expected invocation to a given static method, with a given list of arguments.
There is another way of mocking static methods using JMockit (using Delegate class). I find it more convenient and elegant.
public class Service {
public String addSuffix(String str) { // method to be tested
return Utils.staticMethod(str);
}
}
public class Utils {
public static String staticMethod(String s) { // method to be mocked
String suffix = DatabaseManager.findSuffix("default_suffix");
return s.concat(suffix);
}
}
public class Test {
#Tested
Service service;
#Mocked
Utils utils; // #Mocked will make sure all methods will be mocked (including static methods)
#Test
public void test() {
new Expectations {{
Utils.staticMethod(anyString); times = 1; result = new Delegate() {
public static String staticMethod(String s) { // should have the same signature (method name and parameters) as Utils#staticMethod
return ""; // provide custom implementation for your Utils#staticMethod
}
}
}}
service.addSuffix("test_value");
new Verifications {{
String s;
Utils.staticMethod(s = withCapture()); times = 1;
assertEquals("test_value", s); // assert that Service#addSuffix propagated "test_value" to Utils#staticMethod
}}
}
}
Reference:
https://jmockit.github.io/tutorial/Mocking.html#delegates
https://jmockit.github.io/tutorial/Mocking.html#withCapture
Related
Hi all i receive Nullpointer when trying to execute this unit test.I want to test e class which receive 3 parameters and returns a string. I think i need to make #Before or something else but it didn't works. Do you have suggestions...Thanks !
public class UrlConstructorTest {
private UrlConstructor urlConstructor;
#Before
public void setUp() {
urlConstructor = new UrlConstructor();
}
public static final String TEST_UPDATE_MANIFEST_SR = "/packages/proxyId/test/test1/123/test3/test_test";
#Test
public void constructUpdateManifestSrInSasTokenTest() {
String result = urlConstructor.composeDeviceRegistrationUrl("test","test123","test");
System.out.println(result);
assertNotNull(result);
assertEquals(TEST, result);
}
}
UrlConstructor is define like this:
#Component
public class UrlConstructor {
And this is the method in this class:
public String composeDUrl(String deviceId, String scopeId) {
return String.format(Constants.socpe, tes, test);
}
In Junit5, you should be using #BeforeEach. Or you can get rid of that setUp method completely.
public class UrlConstructorTest {
private final UrlConstructor urlConstructor = new UrlConstructor();
public static final String TEST_SR = "/packages/proxyId/testID/product/testscope/testcomponent/coomponent_up";
#Test
public void constructTest() {
String result = urlConstructor.composeDeviceRegistrationUrl("testID","coomponent_up","testscope");
System.out.println(result);
assertNotNull(result);
assertEquals(TEST_SR, result);
}
}
public class MyXML {
private MessageParser messageParser;
private String valueA;
private String valueB;
private String valueC;
public MyXML (MessageParser messageParser) {
this.messageParser=messageParser;
}
public void build() {
try {
setValueA();
setValueB();
setValueC();
} catch (Exception e) {
e.printStackTrace();
}
}
private void setValueA() {
valueA = messageParser.getArrtibuteUsingXPath("SomeXPath1...");
}
private void setValueB() {
valueB = messageParser.getArrtibuteUsingXPath("SomeXPath2...");
}
private void setValueC() {
valueC = messageParser.getArrtibuteUsingXPath("SomeXPath...");
}
public String getValueA() {
return valueA;
}
public String getValueB() {
return valueB;
}
public String getValueC() {
return valueC;
}
}
So I need to use Mockito to test the builder method. Im fairly new to Mockito could someone give me some example code as to how I might write a test for the builder method?
If you want to suggest any ways I might change the design of the class or make it easier to test let me know.
To test build() you can try :
#RunWith(MockitoJUnitRunner.class)
public class YourTest {
#Mock
private private MessageParser messageParserMock;
// this one you need to test
private MyXML myXML;
#Test
public void test() {
myXML = new MyXML(messageParserMock);
// I believe something like this should work
Mockito.doAnswer(/* check mockito Answer to figure out how */)
.when(messageParserMock).getArrtibuteUsingXPath(anyString());
// you should do this for all your 3 getArrtibuteUsingXPath because setValueA(), setValueB(), setValueC() are called that one and then call build and verify results
myXML.build(); // for instance
assertEquals("something you return as Answer", myXML.getValueA());
}
}
The resource https://static.javadoc.io/org.mockito/mockito-core/2.8.9/org/mockito/Mockito.html#stubbing_with_exceptions might be useful - it describes how to stub void methods call.
Why mockito make a call for stubbed method.
Why it make an actual call for func under when..thenReturn
I have checked when doing debugging.
#Test
public void function(){
MyClassChild obj = mock(MyClassChild.class);
when(obj.func("abc")).thenReturn(3);
}
...
class MyClass {
public int func(String s) {
if (s.equals("abc"))
return 3;
else
return 1;
}
}
class MyClassChild extends MyCLass {
}
I attempted to replay your issue by having the following test:
public class StackTest {
#Test
public void mockedFunction() {
MyClass obj = mock(MyClass.class);
when(obj.func("abc")).thenReturn(3);
assertEquals(3, obj.func("abc"));
}
#Test
public void function() {
MyClass obj = new MyClass();
assertEquals(7, obj.func("abc"));
}
}
and
public class MyClass {
public int func(String s) {
if (s.equals("abc"))
return 7;
else
return 9;
}
}
All tests where executed successfully. Can you show how you are invoking the test?
I have a static method which will be invoking from test method in a class as bellow
public class MyClass
{
private static boolean mockMethod( String input )
{
boolean value;
//do something to value
return value;
}
public static boolean methodToTest()
{
boolean getVal = mockMethod( "input" );
//do something to getVal
return getVal;
}
}
I want to write a test case for method methodToTest by mocking mockMethod.
Tried as bellow and it doesn't give any output
#Before
public void init()
{
Mockit.setUpMock( MyClass.class, MyClassMocked.class );
}
public static class MyClassMocked extends MockUp<MyClass>
{
#Mock
private static boolean mockMethod( String input )
{
return true;
}
}
#Test
public void testMethodToTest()
{
assertTrue( ( MyClass.methodToTest() );
}
To mock your static method:
new MockUp<MyClass>()
{
#Mock
boolean mockMethod( String input ) // no access modifier required
{
return true;
}
};
To mock the static private method:
#Mocked({"mockMethod"})
MyClass myClass;
String result;
#Before
public void init()
{
new Expectations(myClass)
{
{
invoke(MyClass.class, "mockMethod", anyString);
returns(result);
}
}
}
#Test
public void testMethodToTest()
{
result = "true"; // Replace result with what you want to test...
assertTrue( ( MyClass.methodToTest() );
}
From JavaDoc:
Object mockit.Invocations.invoke(Class methodOwner, String methodName, Object... methodArgs)
Specifies an expected invocation to a given static method, with a given list of arguments.
There is another way of mocking static methods using JMockit (using Delegate class). I find it more convenient and elegant.
public class Service {
public String addSuffix(String str) { // method to be tested
return Utils.staticMethod(str);
}
}
public class Utils {
public static String staticMethod(String s) { // method to be mocked
String suffix = DatabaseManager.findSuffix("default_suffix");
return s.concat(suffix);
}
}
public class Test {
#Tested
Service service;
#Mocked
Utils utils; // #Mocked will make sure all methods will be mocked (including static methods)
#Test
public void test() {
new Expectations {{
Utils.staticMethod(anyString); times = 1; result = new Delegate() {
public static String staticMethod(String s) { // should have the same signature (method name and parameters) as Utils#staticMethod
return ""; // provide custom implementation for your Utils#staticMethod
}
}
}}
service.addSuffix("test_value");
new Verifications {{
String s;
Utils.staticMethod(s = withCapture()); times = 1;
assertEquals("test_value", s); // assert that Service#addSuffix propagated "test_value" to Utils#staticMethod
}}
}
}
Reference:
https://jmockit.github.io/tutorial/Mocking.html#delegates
https://jmockit.github.io/tutorial/Mocking.html#withCapture
I am new to jmockit and trying to execute the following online example.
The #MockClass is not working. My BookStore's getBookTitle() method is calling the function of orginal class instead of the mock class.
BookStore class:
public class BookStore {
public String getBookTitle(String isbn){
return BookStoreService.getBookTitle(isbn);
}
}
BookStoreService class:
public class BookStoreService {
public static String getBookTitle(String isbn){
return "Random";
}
}
Test class:
public class BookStoreTest {
private static Map<String, String> bookMap = new HashMap<String, String>(2);
#BeforeClass
public static void setup() {
System.out.println("in setup()");
bookMap.put("0553293354", "Foundation");
bookMap.put("0836220625", "The Far Side Gallery");
}
#MockClass(realClass = BookStoreService.class)
public static class MockBookstoreService {
#Mock
public static String getBookTitle(String isbn) {
System.out.println("in getBookTitle()");
if (bookMap.containsKey(isbn)) {
return bookMap.get(isbn);
} else {
return null;
}
}
}
#Test
public void testGetBookTitle() throws Exception {
System.out.println("in testGetBookTitle()");
final String isbn = "0553293354";
final String expectedTitle = "Foundation";
BookStore store = new BookStore();
String title = store.getBookTitle(isbn);
System.out.println(title); // This prints "Random" instead of "Foundation"
Assert.assertEquals(title, expectedTitle);
}
}
PS: I am using TestNG
Using the latest stable version of jmockit you could do it like this:
#BeforeClass
public static void setup() {
System.out.println("in setup()");
bookMap.put("0553293354", "Foundation");
bookMap.put("0836220625", "The Far Side Gallery");
new MockUp<BookStoreService>() {
#Mock
public String getBookTitle(String isbn) {
System.out.println("in getBookTitle()");
if (bookMap.containsKey(isbn)) {
return bookMap.get(isbn);
} else {
return null;
}
}
};
}
Remove the obsolete block:
public static class MockBookstoreService{...}