Following is the code I am trying to unit test
public final class ClassToBeTested {
public static void function(String arg) {
ProcessBuilder pb = new ProcessBuilder(arg);
//Using pb here
}
}
I want to mock the constructor invocation (new File(arg)), here
I tried using Power Mock :
#PrepareForTest({ClassToBeTested.class})
public class TestClass {
#Test
public void functionTest() throws Exception {
String str = "abc";
ProcessBuilder mockProcessBuilder = PowerMock.createMock(ProcessBuilder.class);
PowerMock.expectNew(ProcessBuilder.class, str).andReturn(mockProcessBuilder);
PowerMock.replay(mockProcessBuilder, ProcessBuilder.class);
ClassToBeTested.function(abc);
}
}
This doesn't seem to work. As new ProcessBuilder(arg) is not returning the mocked object.
Adding #RunWith(PowerMockRunner.class) helped to resolve the issue.
Also using PowerMock.replayAll().
Related
Hi there I wanna test this class in java, but I have problems because only can call the object inside of assertEquals, if I declare this before will avoid the interception de "when" with the method isProduction, how i can clean this class for each test that I will want execute:
public class SalesforceConstants {
public static final String SALESFORCE_APPROVAL =
RuntimeEnvironment.get().isProduction()
? "salesforss#ssd.com"
: "approver#meretest.com";
public static final String SALESFORCE_REQUESTER = "requester.local#meradda.com"; }
public void test(){
try (MockedStatic<RuntimeEnvironment> routingHelperMockedStatic = mockStatic(RuntimeEnvironment.class)) {
RuntimeEnvironment runtime = mock(RuntimeEnvironment.class);
when(runtime.isProduction()).thenReturn(true);
routingHelperMockedStatic.when(RuntimeEnvironment::get).thenReturn(runtime);
}
assertEquals(SalesforceConstants.SALESFORCE_APPROVAL, "salesforss#ssd.com");
}
I am testig a public method and I want to verify if a private method, that have mocked params, is called.
All the answers I have found are using invoke method, but this was removed since JMockit v1.36
public class ClassToTest{
public void methodToTest(){
DependencyClass abc = new DependencyClass();
if(privateMethod1()){
privateMethod2(abc);
}
}
private boolean privateMethod1(){ return true; }
private void privateMethod2(DependencyClass abc){ abc.doStuff(); }
}
public class testClassToTest{
#Mocked
DependencyClass abc;
#Tested
ClassToTest testedClass;
#BeforeEach
public void setUp() {
testedClass = new ClassToTest();
}
#Test
public void testMethod(){
new MockUp<ClassToTest>() {
#Mock
private boolean privateMethod1() {
return true;
}
};
testedClass.methodToTest();
new FullVerificationsInOrder() {{
abc = new DependencyClass();
//Check here if privateMethod2(abc) gets called once
}};
}
You can use Powermock to mock and verify private methods.
Please check https://github.com/powermock/powermock/wiki/MockPrivate
You have two ways:
To level up your method's scope from private to package-private and after it, your method will become visible in the test.
Refactoring your code and encapsulate the private method to Predicate and after it, you can test your primary method and Predicate separately.
You can't test the private method by Junit.
How I understand Mockito.mock create the stub of the service (or another object).
I have simple handler:
public class Handler
{
private HttpSender sender;
public Handler(BigInteger sessiongId) {
RequestHelper helper = RequestHelper.getInstance();
String requestAsText = helper.getCurrentRequest(sessiongId);
StringBuilder stringBuilder = new StringBuilder(requestAsText);
run(stringBuilder);
sender = SenderGenerator.getInstance().create(stringBuilder.toString());
}
public void run(StringBuilder str) {
str.delete(0, 2);
}
}
How I can pass test for this handler with use Mockito?
public class HandlerTest
{
#Test
public void testRun()
{
StringBuilder str = new StringBuilder("1234");
Handler handler = Mockito.mock(Handler.class);
handler.run(str);
Assert.assertEquals("34", str);
}
}
The actual result of this test is 1234 ? Why ?
Because your haldler object in the test method is a mock-object and not a real object the method call handler.run(str) will not do anything as long as you don't tell it what to do.
So a solution would be to tell the mock object to call the real method like this:
public class HandlerTest {
#Test
public void testRun() {
StringBuilder str = new StringBuilder("1234");
Handler handler = Mockito.mock(Handler.class);
when(handler.run(any(StringBuilder.class))).thenCallRealMethod();
handler.run(str);
Assert.assertEquals("34", str.toString());//add toString here, because you are comparing a String to a StringBuilder
}
}
Another way of testing this method would be to make it static so you dont even need to mock anything:
public class Handler {
public Handler(BigInteger sessiongId) {
//...
}
public static void run(StringBuilder str) {
str.delete(0, 2);
}
}
And your test method would look like this:
public class HandlerTest {
#Test
public void testRun() {
StringBuilder str = new StringBuilder("1234");
Handler.run(str);
Assert.assertEquals("34", str.toString());
}
}
Two things:
1. You have mocked the very class you want to test. And you haven't defined any specific behaviour for the mock either. So the call to the test method itself is skipped. You may have to think over what was the purpose of mocking?
2. You are comparing a StringBuilder object with a String, that needs to be corrected too.
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);
}
I am creating a set of junit test classes ,all of which read from the same input data files.I created a test suite as below,but found that I would be replicating the filenames in each test class.
So, how do I do this without repeating the code..
#RunWith(Suite.class)
#SuiteClasses({SomeTests.class,someOtherTests.class})
public class AllTests{
}
-------------------
public class SomeTests{
private String[] allfiles;
public SomeTests() {
allfiles = new String[] {"data1.txt","data2.txt"};
}
#Test
public void testXX1(){
//
}
#Test
public void testXX2(){
//
}
}
public class someOtherTests{
private String[] allfiles;
public someOtherTests() {
allfiles = new String[] {"data1.txt","data2.txt"};
}
#Test
public void testYY(){
//
}
}
I thought I would have to make another class to provide the filenames as a String array..sothat the test classes can initialize the allfiles variable by calling the getFileNames() static method,combining this this with BeforeClass annotation
public class FileNames {
public static String[] getFileNames() {
return new String[]{"data1.txt","data2.txt"};
}
}
public class SomeTests{
private String[] allfiles;
public SomeTests() {
}
#BeforeClass
public void setUp(){
allfiles = FileNames.getFileNames();
}
#Test
public void testXX1(){
//
}
#Test
public void testXX2(){
//
}
}
but I am not sure that is the right way. This will require setUp() to be declared as static ,and that means I will have to make the instance variable allfiles static !
I think this is a common scenario in junit testing ..so can someone please tell me how to do this properly?
Use #Before instead of #BeforeClass, then your setUp() method need not be static.
However, unless you are going to modify your filename array in your tests, you could also create a base class for your tests and declare a protected constant with those names:
public class FileBasedTests {
protected static final String[] FILENAMES = {"data1.txt","data2.txt"}
}
public class SomeTests extends FileBasedTests {
...
}
If you really are concerned about each test having its own copy of those file names, you can write allFiles = FILENAMES.clone().