PowerMockito mock a static method only in one testcase - java

I need to mock a static method only in one test case and wants it to return the original value in all the other testcases.
Class ClassWithStaticMethod
{
public static boolean aStaticMethod(String param)
{
//Some Code;
return value;
}
}
/// Test Class
#RunWith(PowerMockRunner.class)
Class ClassWithStaticMethodTest
{
#Test
testWhenNotMocked()
{
assertTrue(ClassWithStaticMethod.aStaticMethod("str1"));
}
#PrepareForTest({ClassWithStaticMethod.class})
#Test
testWhenMocked()
{
PowerMockito.mockStatic(ClassWithStaticMethod.class);
when(ClassWithStaticMethod.aStaticMethod("str1")).thenReturn(false);
assertFalse(ClassWithStaticMethod.aStaticMethod("str1"));
}
}
But the code is always returning false.

Related

Junit 5 unit test case for static method with layerig

I have a class name LookupCode which is written as below.
class LookupCode {
public static LookUpCode getInstance() {
// This part will have more code for singleton.
return new LookUpCode();
}
public Map getCodeList(String code, String label) {
// return map.
}
}
My service class ABCService using LookupCode class of method getCodeList().
class ABCService {
LookupCode().getInstance().getCodeList("123", "456")`;
}
I wrote the test for ABCService by using Junit5 and Mockito. I am getting the exceptions from mockito saying getInstance() should return LookupCode`.
#Test
void test() {
try(MockedStatic<LookupCode> mockedStatic = Mockito.mockStaticLookupCode.class)) {
mockedStatic.when(() -> LookupCode().getInstance().getCodeList("123", "456")).thenReturn(buildMap());
}
}
You should first mock the result of the static method call .getInstance() and return a mocked instance of your LookukpCode class. Next, provide the stubbing on this mocked instance:
#Test
void test() {
LookupCode mockedLookupInstance = mock(LookupCode.class);
try(MockedStatic<LookupCode> mockedStatic = Mockito.mockStatic(LookupCode.class)) {
mockedStatic.when(LookupCode::getInstance).thenReturn(mockedLookupInstance);
when(mockedLookupInstance.getCodeList("123", "456").thenReturn(yourMap):
}
}
Not sure if deep stubbing works for mocking static methods with Mockito.

Unit testing Boolean method based on other methods return types

New to unit testing and am looking for a way to unit test a Boolean method that is validated by two other methods results.
protected boolean isUpdateNeeded(){
return (method1() && method2());
}
the other methods look like this for this example.
protected boolean method1() {
return false;
}
protected boolean method2() {
return true;
}
But these two methods are/can be Overriden if need be. Idk if that really matter at this point
So my thinking behind the test is this. Find a way to pass true/false to method1 or method2 to meet the required possible outcomes.
#Test
public void testCheckToSeeIfUpdateIsNeeded(){
assertTrue('how to check here');
asserFalse('how to check here');
assertIsNull('was null passed?');
}
If another class extends this and overrides method1 and method2, it's the responsibility of the person developing that class to test the change.
You could mock method1 and method2, but you're then coupling the structure of your class with your test cases, making it harder to make a change later.
Your responsibility here to test the behavior of your class. I see the method in question is called isUpdateNeeded. So let's test that. I'll fill out the class as I imagine it.
class Updater {
Updater(String shouldUpdate, String reallyShouldUpdate) {...}
boolean method1() { return shouldUpdate.equals("yes"); }
boolean method2() { return reallyShouldUpdate.equals("yes!"); }
boolean isUpdateNeeded() { ...}
}
class UpdaterTest {
#Test
void testUpdateIsNeededIfShouldUpdateAndReallyShouldUpdate() {
String shouldUpdate = "yes";
String reallyShouldUpdate = "yes!"
assertTrue(new Updater(shouldUpdate, reallyShouldUpdate).isUpdateNeeded());
}
.... more test cases .....
}
Notice how this test asserts the behavior of the Updater given the inputs, not it's relationship to the existence of some other methods.
If you would like the test to demonstrate what happens if you override the methods, subclass Updater in the test and make the appropriate change.
So, for example you have class:
public class BooleanBusiness {
public boolean mainMethod(){
return (firstBoolean() && secondBoolean());
}
public boolean firstBoolean(){
return true;
}
public boolean secondBoolean() {
return false;
}
}
Then you can write tests like this:
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;
import org.junit.Test;
import org.mockito.Mockito;
public class BooleanBusinessTest {
#Test
public void testFirstOption() {
BooleanBusiness booleanBusiness = Mockito.spy(BooleanBusiness.class);
when(booleanBusiness.firstBoolean()).thenReturn(true);
when(booleanBusiness.secondBoolean()).thenReturn(true);
assertTrue(booleanBusiness.mainMethod());
}
#Test
public void testSecondOption() {
BooleanBusiness booleanBusiness = Mockito.spy(BooleanBusiness.class);
when(booleanBusiness.firstBoolean()).thenReturn(true);
when(booleanBusiness.secondBoolean()).thenReturn(false);
assertFalse(booleanBusiness.mainMethod());
}
}

How to replace method invocation with mock?

I have a class with two methods. I want to replace invocation of second method with expected result.
Here is my class under test
public class A {
public int methodOne() {
return methodTwo(1);
}
public int methodTwo(int param) {
// corresponding logic replaced for demo
throw new RuntimeException("Wrong invocation!");
}
}
And test
public class ATest {
#Test
public void test() {
final A a = spy(new A());
when(a.methodTwo(anyInt())).thenReturn(10);
a.methodOne();
verify(a, times(1)).methodTwo(anyInt());
}
}
Why I'm get an exception when start the test?
Two things that will help you here. First, from the documentation it seems you need to use the do*() api with spy() objects. Second, to call the "real" method you need to declare it specifically using doCallRealMethod()
Here's the updated test that should work for you:
public class ATest {
#Test
public void test() {
final A a = spy(new A());
doReturn(10).when(a).methodTwo(anyInt());
doCallRealMethod().when(a).methodOne();
a.methodOne();
verify(a, times(1)).methodTwo(anyInt());
}
}

JUnit #Parameterized function is run before #BeforeClass in a test suite?

I am using a JUnit test suite to run a few tests, one of which is run multiple times using #Parameterized. I am finding that when I run my tests, the #Parameterized function is run before #BeforeClass. Is this expected behavior or is something else happening? I would have expected that #BeforeClass would run before any of the tests are started.
Here is my test suite:
#RunWith(Suite.class)
#SuiteClasses({ Test1.class, Test2.class })
public class TestSuite {
#BeforeClass
public static void setup() throws Exception {
// setup, I want this to be run before anything else
}
}
Test1 uses #Parameterized:
public class Test1 {
private String value;
// #Parameterized function which appears to run before #BeforeClass setup()
#Parameterized.Parameters
public static Collection<Object[]> configurations() throws InterruptedException {
// Code which relies on setup() to be run first
}
public Test1(String value) {
this.value = value;
}
#Test
public void testA() {
// Test
}
}
How can I fix this to run the #BeforeClass setup() function before running anything else?
This is, unfortunately, working as intended. JUnit needs to enumerate all of the test cases before starting the test, and for parameterized tests, the method annotated with #Parameterized.Parameters is used to determine how many tests there are.
Although beeing a bit different solution, a static block does the trick. Also note, that it must be in the Test1.class. But beside of that it works ;-)
#RunWith(Parameterized.class)
public class Test1 {
static{
System.out.println("Executed before everything");
}
private String value;
// #Parameterized function which appears to run before #BeforeClass setup()
#Parameterized.Parameters
public static Collection<Object[]> configurations() throws InterruptedException {
// Code which relies on setup() to be run first
}
public Test1(String value) {
this.value = value;
}
#Test
public void testA() {
// Test
}
}
Recently ran into similar issue and solved problem using Function. Example below.
#RunWith(Parameterized.class)
public class MyClassTest {
#Parameterized.Parameters
public static Iterable functions() {
return Arrays.<Object, Object>asList(
param -> new Object()
);
}
Object param;
Function function;
public MyClassTest(Function f) {
this.function = f;
}
#Before
public void before() {
// construct dependency
param = "some value";
}
#Test
public void test() {
assertThat(myClass.doSomething(function.apply(param)), is(equalTo(expectedValue)));
}
}
In your scenario, do database setup in #Before or #BeforeClass then inject into function
I found a hack to force a code segment to run before all other methods that are annotated with #Parameterized.Parameters.
Just create a parameterized dummy test as follows:
#RunWith(Parameterized.class)
public class DummyInitTest
{
#Parameterized.Parameters
public static Collection<?> constructorFeeder()
{
// Your setup here. This will run before anything else.
// Return empty list so no tests will be executed for this test class.
return ImmutableList.of();
}
}
Then in your test suite, add this test first:
#RunWith(Suite.class)
#SuiteClasses({ DummyInitTest.class, Test1.class, Test2.class })
public class TestSuite {
// ...
}
Hoping this can help someone, I simply did it this way:
//#BeforeClass does not run before Parameters annotation
public static void beforeClassSetup() throws IOException {
InputStream is = Test.class.getResourceAsStream("/TestData.json");
// load data...
}
#Parameters(name = "testProductFunctionality")
public static Collection<Object[]> data() throws IOException {
beforeClassSetup();
// create parameters...
}
#Test
public void testProductFunctionality() {
//...

Non-void test methods in JUnit 4

I would like a JUnit 4 test class to implement the same interface as the class its testing. This way, as the interface changes (and it will, we're in early development), the compiler guarantees that corresponding methods are added to the test class. For example:
public interface Service {
public String getFoo();
public String getBar();
}
public class ServiceImpl implements Service {
#Override public String getFoo() { return "FOO"; }
#Override public String getBar() { return "BAR"; }
}
public class ServiceTest implements Service {
#Override
#Test
public String getFoo() {
//test stuff
}
#Override
#Test
public String getBar() {
//test stuff
}
}
When I try this, I get an error: "java.lang.Exception: Method getFoo() should be void",
presumably because test methods must return void. Anybody know of any way around this?
I have to admit, it is a neat trick, though it doesn't scale well to multiple test scenarios.
Anyways, you can use custom runner. For example:
#RunWith(CustomRunner.class)
public class AppTest {
#Test
public int testApp() {
return 0;
}
}
public class CustomRunner extends JUnit4ClassRunner {
public CustomRunner(Class<?> klass) throws InitializationError {
super(klass);
}
protected void validate() throws InitializationError {
// ignore
}
}
A more natural way would probably be to use a code coverage tool, such as Cobertura. It integrates with JUnit nicely AND it shows you cases where your tests may be deficient in some cases (there are many cases such a tool won't catch though).

Categories