Static Variable test switching enviroment Java - java

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");
}

Related

How to make Unit test passed with use Mockito?

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.

Mockito wanted but not invoked utility class

I am making a unit test for class in my app, it just a simple class and I thought i did everything right but the test failed saying
Wanted but not invoked:
mContextWeakReference.get();
-> at rahmat.com.app.utility.backwardcompatibility.StringResourceUtilTest.getString(StringResourceUtilTest.java:40)
Actually, there were zero interactions with this mock.
this is the class to be tested
public class StringResourceUtil {
private static StringResourceUtil sInstance;
private WeakReference<Context> mContextWeakReference;
public static StringResourceUtil getInstance() {
return sInstance;
}
#Inject
public StringResourceUtil(Context context) {
mContextWeakReference = new WeakReference<>(context);
sInstance = this; //NOSONAR
}
public String getString(int resId) {
return mContextWeakReference.get().getString(resId);
}}
this is unit test I made
public class StringResourceUtilTest {
private StringResourceUtil mResourceUtil;
#Mock
private Context mContext;
#Mock
private WeakReference<Context> mContextWeakReference;
#Before
public void setUp(){
MockitoAnnotations.initMocks(this);
mResourceUtil = new StringResourceUtil(mContext);
}
#Test
public void getString() {
int resId = 123;
mResourceUtil.getString(resId);
verify(mContextWeakReference).get().getString(eq(resId));
}}
any help would be much appreciated, thanks
Your StringUtil class is always creating a new object of mContextWeakReference object and even if you are making it, it won't inject automatically ( for that you use injectMock but no use here, since new object creation always happens internally).
public class StringResourceUtilTest {
private StringResourceUtil mResourceUtil;
#Mock
private Context mContext;
#Before
public void setUp(){
MockitoAnnotations.initMocks(this);
mResourceUtil = new StringResourceUtil(mContext);
// setup mock return type
// mock objects are not real,so need to moeck the behavior of method as well
when(mContext.getString(R.string.a123)).thenReturn("123");
}
#Test
public void getString() {
int resId = R.string.a123;
// check the return type
assertEquals("123",mResourceUtil.getString(resId));
}
}
Note: To verify the internal working, read
What is the difference between mocking and spying when using Mockito?
Because you creating mContextWeakReference = new WeakReference<>(context); in constructor, it will never been a mock in StringResourceUtil.
You can set prepared mock mContextWeakReference by using
org.springframework.test.util.ReflectionTestUtils.setField(mResourceUtil , "mContextWeakReference", mContextWeakReference);
Otherwise you should modifying StringResourceUtil class to be a testable

Mockito: Spying calls within the constructor (Java) [duplicate]

This question already has answers here:
Test class with a new() call in it with Mockito
(7 answers)
Closed 5 years ago.
This is not a duplicate of Test class with a new() call in it with Mockito. I'm trying to write a test to verify that certain methods are being called within the constructor of my spy object (mockToyFacade).
The class under test is ToyFactoryFacade. The idea is clients interact with the ToyFactoryFacade (which wraps a ToyFactory) to generate ToyFacades, which itself is a wrapper around the Toy object.
What I am trying to verify with Mockito?
I want to verify that addToyName(toyName) and addCreationTime(creationTimestamp) are being called on the ToyFacade. Both of these methods are called in the constructor of the ToyFacade.
What's the issue?
When I try to spy the ToyFacade, and verify that both aforementioned methods are called, I receive an error, which says "Actually, there were zero interactions with this mock." When I call the methods separately (i.e., not via the constructor), the verification check out correctly. I'm not sure what I'm doing incorrectly.
Test Code
public class ToyFactoryFacadeTest {
private Toy mockToy;
private ToyFacade mockToyFacade;
// System under test.
private ToyFactoryFacade toyFactoryFacade;
private ToyFactory mockToyFactory;
#Before
public void setup() {
mockToy = mock(Toy.class);
mockToyFacade = spy(new ToyFacade(mockToy, "Phone", System.currentTimeMillis()));
mockToyFactory = mock(ToyFactory.class);
toyFactoryFacade = new ToyFactoryFacade(mockToyFactory) {
#Override
public Toy getToyFacade(String toyName, long creationTimestamp){
return mockToyFacade;
}
};
}
#Test
public void testToyFactoryFacade() {
toyFactoryFacade.initializeAndGetToy("Phone", System.currentTimeMillis());
verify(mockToyFacade).addToyName("Phone");
verify(mockToyFacade).addCreationTime(anyLong());
}
}
Source Code
public class ToyFactoryFacade {
private final ToyFactory toyFactory;
public ToyFactoryFacade(ToyFactory toyFactory) {
this.toyFactory = toyFactory;
}
public ToyFacade initializeAndGetToy(String toyName, long creationTimestamp)
{
getToyFacade(toyName, creationTimestamp);
}
// For testing.
protected ToyFacade getToyFacade(String toyName, long creationTimestamp
{
return new ToyFacade(toyFactory.newToy(), toyName, creationTimestamp);
}
}
public class ToyFactory {
public Toy newToy() {
return new Toy();
}
}
public class ToyFacade {
private final Toy toy;
public ToyFacade(Toy toy, String toyName, long creationTimeStamp) {
this.toy = toy;
addToyName(toyName);
addCreationTime(creationTimestamp);
}
public void addToyName(String name) {
toy.addToyName(toyName);
}
public void addCreationTime(long timestamp) {
toy.addCreationTime(timestamp);
}
}
public class Toy {
public String toyName;
public String creationTimestamp;
public void addToyName(String name) {
toyName = name;
}
public void addCreationTime(long timestamp) {
creationTimestamp = timestamp;
}
}
Your test isn't doing what you expect because the method calls that you're trying to verify have already taken place before you create your spy. What you really want to do is to test the effect of those two method calls, rather than the calls themselves. This would look something like
verify(mockToy).addToyName("Phone");
verify(mockToy).addCreationTime(timestamp);
where timestamp is whatever you pass in in the setUp method.

Mocking a constructor inside a static method

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().

how to initialize common resource names in multiple junit4 test classes

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().

Categories

Resources