Handle string bundle in JUnit Test case - string

How can I handle the String bundles, real one or faked?
I have a lots of cases affect each other of the String bundle, some legal codes write as below:
//example
private static I18n myInstance = I18n.getInstance().get(Example.class);
If all the cases run together, then this string bundle value will never reload because of it is static, actually different products have different string bundle values, then cause some case failed.
If not use the real string, the codes cannot run, because of the codes logic is base on the string bundle, seems only way is use real string bundle or fake the real value.
//example
if(isValue(myRB.getString("key")))
{
.....
}

You could inject the I18n instance into your class under test and mock I18n in the test.
public class YourClass {
private final I18n i18n;
public YourClass(I18n i18n) {
this.i18n = i18n;
}
}

Related

I have a requirement to write unit test using jest of a non-export typescript class methods

How to access non-export typescript class in unit test file?
How to access private static method of non-export typescript class in unit test file?
// SomeClass.ts
class SomeClass {
private static someMethod() {
// some code
}
}
// SomeClass.test.ts >> ??
If you don't really care on typing, you may use #ts-ignore. JS will let you do whatever you want after all; (or use more safe as {someMethod: ()=>void})
If your functions are actually private (start with #), then, well, there's absolutely nothing simple you can do with that

Mockito.mockConstruction provides null logger in the tested class

I want to test the method Utility#fromJson. In order to do that I need to mock the LoggerBean constructor which has some JNDI code in it.:
public class Utility {
private static Logger log = LoggerBean.getLoggerBean().getLogger(Utility.class);
private static ObjectMapper mapper = new ObjectMapper();
public static <T> T fromJson(String json, Class<T> type) {
try {
return mapper.readValue(json, type);
} catch (IOException e) {
//during test log is null here
log.error("json deserialization failed", e);
}
return null;
}
}
In the following test class I can mock the constructor with mockito and want that mocked Logger should be present in the Utility class. However the log in the Utility class is null during the test.
class UtilityTest {
#Test
void testFromJson() throws Exception {
// mocking constructor
try (MockedConstruction<LoggerBean> mocked = Mockito.mockConstruction(LoggerBean.class, (mock, context) -> {
// further stubbings ...
when(mock.getLogger(getClass())).thenReturn(Logger.getLogger(getClass()));
})) {
// the logger here works
// Logger logger = Logger.getLogger(getClass());
//logger.info("-----------------");
String json = " {\"key\":\"k1\",\"value\":\"v1\"}";
assertNotNull(Utility.fromJson(json, Tuple.class));
}
}
}
I am using mockito-inline version 3.11.2.
Please suggest how to get the mocked log in the Utility class.
A distinct non-answer: don't even try.
If you really absolutely want a static method, then why not create a small utility class that does the same thing in a non static way (where you then can use the ctor of that class to insert your dependencies). And then maybe and keep a static instance of that class for your static method.
Remember that static comes with a lot of disadvantages. Especially in this case: if you can't test this static utility code without doing all this extra work, then you just introduced something that will interfere with unit testing any of the code that is going to use the static method.
In other words: you created hard to test code. Now you are facing the consequences of that, and your answer is to reach for the biggest hammer in the toolbox. But hammering a screw into the wall, yes that is possible, but is rarely a good idea. Instead you pick up a nail, or you go with the screw, but a screwdriver.
The real solution: step back, and remember to only only only ever use static for production code when doing so does not interfere with your ability to do proper, decent, simple unit testing.
Other readers: do not see this answer as discouragement to give the correct technical answer please!
So I finally realized that there is no need to mock the constructor of LoggerBean so that the following works:
private static Logger log = LoggerBean.getLoggerBean().getLogger(Utility.class);
So Mockito.mock(LoggerBean.class) already skips the call to the constructor.
class UtilityTest {
private static Logger log = LoggerBean.getLoggerBean().getLogger(UtilityTest.class);
#Test
void testFromJson() throws Exception {
try (MockedStatic<LoggerBean> mockedStaticLoggerBean = Mockito.mockStatic(LoggerBean.class)) {
LoggerBean loggerBeanMocked = Mockito.mock(LoggerBean.class);
when(loggerBeanMocked.getLogger(Utility.class)).thenReturn(pp);
mockedStaticLoggerBean.when(() -> LoggerBean.getLoggerBean()).thenReturn(loggerBeanMocked);
String json = " {\"key\":\"k1\",\"value\":\"v1\"}";
assertNotNull(Utility.fromJson(json, Tuple.class));
}
}
}
Now the Utility#fromJson will get the logger from UtilityTest class.

How to Stop static initialization with PowerMockito

I am working on an API for work, we use a shared library for multiple projects for the purposing of our logging framework. The class used uses all static methods for its calls.
I am trying to Unit test an API call, I can not have it call anything on the Logging class, else it will fail.
I have tried using Powermock, but it fails on
PowerMockito.mockStatic(LoggingFramework.class);
Mockito.when(LoggingFramework.startACall(anyString())).thenReturn("someTimestamp");
returning a
ClassCastException: org.apache.logging.slf4j.SLF4JLoggerContext cannot be cast to org.apache.logging.log4j.core.LoggerContext
the line in LoggingFramework that throws it, is inside a static initializer block outside of any methods in the class.
In order to suppress static initialization you should use #SuppressStaticInitializationFor. So your code will look like this:
#RunWith(PowerMockRunner.class)
#SuppressStaticInitializationFor("so.LoggingFramework") //here goes fully-qualified name of a class
public class LoggingFrameworkTest {
#Test
public void test() {
//given:
PowerMockito.mockStatic(LoggingFramework.class);
Mockito.when(LoggingFramework.foo(anyString())).thenReturn("stub");
//when:
String foo = LoggingFramework.foo("ignored");
//then:
PowerMockito.verifyStatic(LoggingFramework.class, Mockito.times(1));
LoggingFramework.foo(anyString()); //two-step verification of a static method
assertThat(foo, equalTo("stub"));
}
}
Verification of a static method is performed in two steps. It is explained here

Mockito implemetation for formhandlers in ATG

I am new to Mockito as a concept. Can you please help me understand using Mockito for formhandlers in ATG. Some examples will be appreciated.
There is a good answer (related to ATG) for other similar question: using-mockito-for-writing-atg-test-case. Please review if it includes what you need.
Many of ATG-specific components (and form handlers particularly) are known to be "less testable" (in comparison to components developed using TDD/BDD approach), b/c design of OOTB components (including reference application) doesn't always adhere to the principle of having "Low Coupling and High Cohesion"
But still the generic approach is applicable for writing unit-tests for all ATG components.
Below is a framework we've used for testing ATG FormHandlers with Mockito. Obviously you'll need to put in all the proper bits of the test but this should get you started.
public class AcmeFormHandlerTest {
#Spy #InjectMocks private AcmeFormHandler testObj;
#Mock private Validator<AcmeInterface> acmeValidatorMock;
#Mock private DynamoHttpServletRequest requestMock;
#Mock private DynamoHttpServletResponse responseMock;
private static final String ERROR1_KEY = "error1";
private static final String ERROR1_VALUE = "error1value";
#BeforeMethod(groups = { "unit" })
public void setUp() throws Exception {
testObj = new AcmeFormHandler();
initMocks(this);
}
//Test the happy path scenario
#Test(groups = { "unit" })
public void testWithValidData() throws Exception {
testObj.handleUpdate(requestMock, responseMock);
//Assume your formhandler calls a helper method, then ensure the helper method is called once. You verify the working of your helper method as you would do any Unit test
Mockito.verify(testObj).update(Matchers.refEq(requestMock), Matchers.refEq(responseMock), Mockito.anyString(), (AcmeBean) Mockito.anyObject());
}
//Test a validation exception
#Test(groups = { "unit" })
public void testWithInvalidData() throws Exception {
Map<String, String> validationMessages = new HashMap<String, String>();
validationMessages.put(ERROR1_KEY, ERROR1_VALUE);
when(acmeValidatorMock.validate((AcmeInterface) Mockito.any())).thenReturn(validationMessages);
testObj.handleUpdate(requestMock, responseMock);
assertEquals(1, testObj.getFormExceptions().size());
DropletFormException exception = (DropletFormException) testObj.getFormExceptions().get(0);
Assert.assertEquals(exception.getMessage(), ERROR1_VALUE);
}
//Test a runtime exception
#Test(groups = { "unit" })
public void testWithRunProcessException() throws Exception {
doThrow(new RunProcessException("")).when(testObj).update(Matchers.refEq(requestMock), Matchers.refEq(responseMock), Mockito.anyString(), (AcmeBean) Mockito.anyObject());
testObj.handleAddGiftCardToCart(requestMock, responseMock);
assertEquals(1, testObj.getFormExceptions().size());
DropletFormException exception = (DropletFormException) testObj.getFormExceptions().get(0);
Assert.assertEquals(exception.getMessage(), GENERAL_ERROR_KEY);
}
}
Obviously the above is just a framework that fit in nicely with the way in which we developed our FormHandlers. You can also add validation for redirects and stuff like that if you choose:
Mockito.verify(responseMock, Mockito.times(1)).sendLocalRedirect(SUCCESS_URL, requestMock);
Ultimately the caveats of testing other people's code still applies.
Here's what I do when I unit test a form handler (at least until I manage to release a major update for AtgDust). Note that I don't use wildcard imports, so I'm not sure if this causes any namespace conflicts.
import static org.mockito.Mockito.*;
import static org.mockito.MockitoAnnotations.initMocks;
import org.junit.*;
import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.*;
import atg.servlet.*;
import some.form.handler.FormHandler;
#RunWith(JUnit4.class)
public class FormHandlerTest {
#Mock DynamoHttpServletRequest request;
#Mock DynamoHttpServletResponse response;
FormHandler handler;
#Before
public void setup() {
initMocks(this);
handler = new FormHandler();
}
#Test
public void testSubmitHandlerRedirects() {
handler.handleSubmit(request, response);
verify(response).sendLocalRedirect(eq("/success.jsp"), eq(request));
assertThat(handler.getFormError(), is(false));
}
}
The basic idea is to set up custom behavior for mocks/stubs using when() on the mock object method invocation to return some test value or throw an exception, then verify() mock objects were invoked an exact number of times (in the default case, once), and do any assertions on data that's been changed in the form handler. Essentially, you'll want to use when() to emulate any sort of method calls that need to return other mock objects. When do you need to do this? The easiest way to tell is when you get NPEs or other runtime exceptions due to working with nulls, zeros, empty strings, etc.
In an integration test, ideally, you'd be able to use a sort of in-between mock/test servlet that pretends to work like a full application server that performs minimal request/session/global scope management. This is a good use for Arquillian as far as I know, but I haven't gotten around to trying that out yet.

Usage of static and final modifiers in Groovy

class GroovyHello {
public String execute() {
println("Test String is " + TEST)
}
private static final String TEST = "Test"
}
Output for the above snippet in Groovy V.1.6.3 is
Test String is Test
Output for the above snippet in Groovy V.1.8.6 is
Test String is null
The above snippet prints the string successfully if I modify the declaration to have either static (private static String TEST = "Test") or final (private final String TEST = "Test"), but not both.
My theory that since object Static and Private then you don't have access to it as it is a separate object. However if it is just private then your method is part of the object and it has access to it. If it is just static then you have access to the field - the field is public by default.
We noticed this happening when we had Groovy++ in the runtime classpath from other transitive dependencies. If that's the case, you might look at that.

Resources