Monday, June 01, 2020
Salesforce Layout - Clickable Address Field
Posted by sathish at 6/01/2020 11:42:00 PM 0 comments
Labels: Salesforce
Saturday, April 23, 2016
Unit Testing Log Statements
Sometimes asserting on a log statement might be the only way of validating a method call. One way of asserting log statements is to create a custom appender and attaching it to the logger to capture the logs. log4j-api
provides the framework to create a custom appender.
import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.Layout; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.appender.AbstractAppender; import java.io.Serializable; import java.util.ArrayList; import java.util.List; public class CustomAppender extends AbstractAppender { private ListFollowing method adds the custom appender to the logger:messages = new ArrayList<>(); public CustomAppender(String name, Filter filter, Layout layout) { super(name, filter, layout); } public CustomAppender(String name, Filter filter, Layout layout, boolean ignoreExceptions) { super(name, filter, layout, ignoreExceptions); } @Override public void append(LogEvent event) { byte[] data = getLayout().toByteArray(event); messages.add(new String(data).trim()); // optional trim } @Override public void stop() { } public List getMessages() { return messages; } }
private void setUpLogHandler() { final LoggerContext ctx = (LoggerContext) LogManager.getContext(false); final AbstractConfiguration config = (AbstractConfiguration) ctx.getConfiguration(); // Create and add the appender customAppender = new CustomAppender("Custom", null, PatternLayout.createDefaultLayout()); customAppender.start(); config.addAppender(customAppender); // Create and add the logger AppenderRef[] refs = new AppenderRef[]{AppenderRef.createAppenderRef("Custom", null, null)}; LoggerConfig loggerConfig = LoggerConfig.createLogger("false", Level.INFO, ClassUnderTest.class.getCanonicalName(), "true", refs, null, config, null); loggerConfig.addAppender(customAppender, null, null); config.addLogger(ClassUnderTest.class.getCanonicalName(), loggerConfig); ctx.updateLoggers(); }Below is an example test method which asserts on a method that logs:
@Test public void logTest() { setUpLogHandler(); ClassUnderTest ct = new ClassUnderTest(); ct.methodThatLogs(); assertThat(customAppender.getMessages(), hasItem("new log message")); }
Posted by sathish at 4/23/2016 12:09:00 AM 0 comments
Thursday, April 21, 2016
Git - Rewriting Commit
Git provides an option to modify the last commit. For staging follow the normal method:
git add .After staging the files, use the
--amend
option to staged files to the last commit:
git commit --amendIf no commit message is provided with
-m
option the previous commit message will be prompted by default. On the other hand to amend a commit without changing its commit message use the --no-edit
option.
Posted by sathish at 4/21/2016 10:23:00 PM 0 comments
Labels: git
Wednesday, April 20, 2016
Parameterized JUnit Tests
JUnitParams provides a runner - JUnitParamsRunner, to add parameterized tests in a test class. With this runner parameterized and non-parameterized test methods can be combined in the same class.
@RunWith(JUnitParamsRunner.class) public class ParameterizedTests { @Parameters({"1, true", "2, false"}) @Test public void test1(int num, boolean result) { assertThat(num == 1, is(result)); } }To pass in objects or null values, a separate method can be setup, which then can be added to the
@Parameters
annotation.
@RunWith(JUnitParamsRunner.class) public class ParameterizedTests { private Object[] params() { return $( $(1, true), $(2, false) ); } @Parameters(method = "params") @Test public void test1(int num, boolean result) { assertThat(num == 1, is(result)); } }
Posted by sathish at 4/20/2016 10:09:00 PM 0 comments
Wednesday, April 13, 2016
Maven Auto Increment Version
Maven update-versions is a handy goal to increment version number of a project. This is especially useful for large multi-module maven projects.
mvn release:update-versionsThe above command prompts for the new version for each module in the project. The prompts can be avoided by using the option autoVersionSubmodules. This will set each module version to be same as the parent POM.
mvn releae:update-versions -DautoVersionSubmodules=trueThe goal can be run in non-interactive mode using batch-mode.
mvn --batch-mode release:update-versionsAbove command will auto increment the version without prompts. A specific version can also be specified:
mvn --batch-mode release:update-versions -DdevelopmentVersion=1.1-SNAPSHOT
Posted by sathish at 4/13/2016 07:43:00 PM 0 comments
Labels: maven
Saturday, September 07, 2013
Abstract Factory
The Abstract Factory pattern provides an interface that delegates creation calls to one or more concrete classes in order to deliver specific objects. Following is the definition provided for the pattern in the GoF book on Design Patterns: Abstract Factory provides an interface for creating families of related or dependent objects without specifying their concrete classes. Abstract factory relies on object composition – i.e. object creation is implemented in methods exposed in the factory methods. The intent of the pattern is to create families of related objects without having to depend on their concrete classes. First we define the interface and implementation of the object that we want to create: public interface Car { public void setDescription(String description); public void refuel(); } public class EVCar implements Car { @Override public void setDescription(String description) { // set description } @Override public void refuel() { // electric charging } } public class HybridCar implements Car { @Override public void setDescription(String description) { // set description } @Override public void refuel() { // refuel with gas } } Now we define the factories, starting with an abstract factory: public interface AbstractCarFactory { public Car createCar(); } Next the actual implementations of the factory: public class EVCarFactory implements AbstractCarFactory { @Override public Car createCar() { EVCar evCar = new EVCar(); return evCar; } } public class HybridCarFactory implements AbstractCarFactory { @Override public Car createCar() { HybridCar hybridCar = new HybridCar(); return hybridCar; } } Now let's test drive this factory: public class AbstractFactoryTest { AbstractCarFactory abstractCarFactory = null; @Test public void evCarFactoryTest() { abstractCarFactory = new EVCarFactory(); abstractCarFactory.createCar(); } @Test public void hybridCarFactoryTest() { abstractCarFactory = new HybridCarFactory(); abstractCarFactory.createCar(); } } While the pattern hides the implementation details from the client, there is always a chance that the underlying system will need to change – for example new attributes might be added to Car or AbstractCarFactory, which would mean a change to the interface that the client was relying on, thus breaking the API.
Posted by Sathish at 9/07/2013 10:58:00 AM 0 comments
Tuesday, August 13, 2013
Priority Queue
Posted by Sathish at 8/13/2013 02:10:00 AM 0 comments