Implementing Factory Pattern and Gettingt NullPointerException, unable to figure out can somebody help me to fix - nullpointerexception

I am posting this code in which I implemented factory method,Code is compiled successfully but null pointer exception occurs at run time and I am unable to figure it out, I know when an object reference points to nothing then this Exception occurs but in my case I am unable to figure out,Can somebody suggest me the fix here I am posting the code.
import java.util.Scanner;
abstract class Plan
{
protected double rate;
public abstract void getRate();
public void calculateBill(int totalUnitsConsume)
{
System.out.println(totalUnitsConsume*rate);
}
}
class DomesticPlan extends Plan
{
public void getRate()
{
rate=3.5;
}
}
class CommercialPlan extends Plan
{
public void getRate()
{
rate=7.50;
}
}
class InstitutionalPlan extends Plan
{
public void getRate()
{
rate=5.50;
}
}
class PlanFactory
{
public static Plan getPlan(String planType)
{
if(planType==null)
{
return null;
}
if (planType.equalsIgnoreCase("DOMESTIC PLAN"))
{
return new DomesticPlan();
}
else if(planType.equalsIgnoreCase("COMMERCIAL PLAN"))
{
return new CommercialPlan();
}
else if (planType.equalsIgnoreCase("INSTITUTION PLAN"))
{
return new InstitutionalPlan();
}
return null;
}
}
public class ElectricityBill
{
public static void main(String ... qwe)
{
int choice;
System.out.println("Choose The Plan type");
System.out.println("1.Domestic Plan");
System.out.println("2.Commercial Plan");
System.out.println("3.Institution Plan");
Scanner sc=new Scanner(System.in);
choice=sc.nextInt();
if(choice>3)
{
System.out.println("Wrong choice entered");
}
else
{
System.out.println("You chose Plan no.:"+ choice);
}
switch(choice)
{
case 1 : Plan p=PlanFactory.getPlan("DomesticPlan");
p.getRate();
p.calculateBill(100);
break;
case 2 : Plan p2=PlanFactory.getPlan("CommercialPlan");
p2.getRate();
p2.calculateBill(300);
break;
case 3 : Plan p3=PlanFactory.getPlan("InstitutionalPlan");
p3.getRate();
p3.calculateBill(250);
break;
default : System.out.println("May be you entered wrong choice");
}
}
}
Output
I:\Data>java ElectricityBill
Choose The Plan type
1.Domestic Plan
2.Commercial Plan
3.Institution Plan
1
You chose Plan no.:1
Exception in thread "main" java.lang.NullPointerException
at ElectricityBill.main(ElectricityBill.java:96)

51. planType.equalsIgnoreCase("DOMESTIC PLAN")
...
96. PlanFactory.getPlan("DomesticPlan")
Here none of the if...else block is getting executed, thus getPlan is returning null.
Please change "DomesticPlan" to "DOMESTIC PLAN" in line 96

You missed a space inside 'DomesticPlanin your code, so your factory can not match any string and returns null, just correct it toDomestic Plan`

It's because your factory is not returning a plan in that case. You are doing PlanFactory.getPlan("DomesticPlan") (no space in DomesticPlan) but within your getPlan method you are looking for "DOMESTIC PLAN" (with space) and therefore Plan p is null. The exception is thrown immediately after, where you are calling the getRate method on the null Plan.
You should null-check when you get a value from the factory, e.g. if (p != null) { p.getRate(); ... }

Related

Intellitest Pex Parameterize Mock

public enum SystemConstants
{
SystemTypeDocument,
ApplicationTypeDocument
}
public interface ISystemBaseObject
{
SystemConstants SystemType();
}
public class ExploreMockExample
{
ISystemBaseObject systemBaseObject;
public ExploreMockExample(ISystemBaseObject systemObject)
{
systemBaseObject = systemObject;
}
public int MethodToBeTested()
{
if (systemBaseObject.SystemType() == SystemConstants.SystemTypeDocument)
{
return 1;
}
else
{
return 2;
}
}
}
Using intellitest along with NUnit3.
When I right click MethodToBeTested, and then select run intellitest, expected outcome is Intellitest test should achieve maximum code coverage and create test case with valid test data to cover both if (systemBaseObject.SystemType() == SystemConstants.SystemTypeDocument) and else branch statement.
Some blogs suggested to create factory for class and create mock object of interface. And use PexChoose static method to allow pex framework to explore code to achieve maximum code coverage.
[PexFactoryMethod(typeof(ExploreMockExample))]
public static ExploreMockExample CreateMock()
{
var mockComosBaseObject = new Mock<ISystemBaseObject>();
mockComosBaseObject.Setup(c =>c.SystemType()).
Returns(PexChoose.EnumValue<SystemConstants>(nameof(SystemConstants)));
return new ExploreMockExample(mockComosBaseObject.Object);
}
With above setup, Intellitest could above to generate only one test case which is covering if statement, if (systemBaseObject.SystemType() == SystemConstants.SystemTypeDocument).
What can be done, to allow intellitest to create test case which will cover else statement having result value as 2.
Create mock implementation for your interface. Like mentioned below,
public class SystemBaseObject : ISystemBaseObject
{
public SystemConstants SystemType()
{
return PexChoose.EnumValue<SystemConstants>("SystemConstants");
}
}
PexChoose will help intellitest to explore code, return value will depend upon uses of SystemConstants in original class.
Then, create factory of ExploreMockExample using SystemBaseObject,
[PexFactoryMethod(typeof(ExploreMockExample))]
public static ExploreMockExample Create()
{
return new ExploreMockExample(new SystemBaseObject());
}
Run Intellitest on actual method MethodToBeTested, Intellitest will create 2 unit test case to cover both if else branch statement.
First test case,
[PexGeneratedBy(typeof(ExploreMockExampleTest))]
public void MethodToBeTested806()
{
ExploreMockExample exploreMockExample;
int i;
exploreMockExample = ExploreMockExampleFactory.Create();
i = this.MethodToBeTested(exploreMockExample);
PexAssert.AreEqual<int>(1, i);
PexAssert.IsNotNull((object)exploreMockExample);
}
Kindly observe PexAssert.AreEqual(1, i), which will cover if branch.
Second test case,
[PexGeneratedBy(typeof(ExploreMockExampleTest))]
public void MethodToBeTested792()
{
ExploreMockExample exploreMockExample;
int i;
exploreMockExample = ExploreMockExampleFactory.Create();
IPexChoiceRecorder choices = PexChoose.Replay.Setup();
choices.NextSegment(1).DefaultSession
.At(0, "SystemConstants", (object)(SystemConstants.ApplicationTypeDocument));
i = this.MethodToBeTested(exploreMockExample);
PexAssert.AreEqual<int>(2, i);
PexAssert.IsNotNull((object)exploreMockExample);
}
Kindly observe PexAssert.AreEqual(2, i), which will cover else branch.
Using PexChoose.Replay.Setup() it will return IPexChoiceRecorder, and it will make choice about to have SystemConstants.ApplicationTypeDocument as argument value to cover else block.

Do an action when an error occurs RxJava

I need to create a folder when it doesn't exist. In my case, the only way to do so is to capture the error and handle it to create the folder wanted.
But all i can find is
public static Observable<Boolean> folderExists(final Context context, final String targetPath, final String currentpath) {
Application application = Application.get(context);
//i browse the folder to get all the items
return browseFolderObservable(context,currentpath)
.subscribeOn(application.defaultSubscribeScheduler())
.doOnError(new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
BsSdkLog.d("Error no file found");
}
})
.map(new Func1<ArrayList<Item>, Boolean>() {
#Override
public Boolean call(ArrayList<Item> items) {
if(items.isEmpty()) {
BsSdkLog.d(" No items");
return false;
}else {
for(int i=0;i<items.size();i++)
{
Item item=items.get(i);
BsSdkLog.d(item.toString());
}
BsSdkLog.d("Right-here");
return true;
}
}
});
}
I want to call the method that i have that creates the folder when the error occurs but i don't know how to do that.
I'm new to this so i'd really appreciate the help
Thanks
The basic principe looks like this. I used the Java NIO library for testing.
The method 'createFolder' just wraps creating a folder. The test 'name' invokes the Single and checks for an Exception. If it is an IOException it will return a fallback value. You may do something different in there. You just provide a fallback single. If it is an error different from IOException, it will return the error.
#Test
void name() throws Exception {
final String TO_CREATE = "/home/sergej/Downloads/Wurstbrot";
this.createFolder(TO_CREATE)
.onErrorResumeNext(throwable -> { // handle Exception:
// Validate Exception
if (throwable instanceof IOException) {
// Return fallback
return Single.just(Paths.get("/home/sergej/Downloads/"));
}
return Single.error(throwable);
})
.test()
.await()
.assertValueCount(1)
.assertValue(path -> path.endsWith(TO_CREATE))
.assertNoErrors();
}
private Single<Path> createFolder(String p) {
return Single.defer(() -> { // may throw some IOException
Path path = Paths.get(p);
if (!Files.exists(path)) {
Path createdDirectory = Files.createDirectory(path); // will throw if already exists
return Single.just(createdDirectory);
}
// Or just return Path, because it already exists???
return Single.error(new IOException("Already exists"));
});
}

How to print the number of failures for every test case using SoftAssert in TestNG

I have a test case that performs the following:
#Test
public void testNumber() {
SoftAssert softAssert = new SoftAssert();
List<Integer> nums = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
for (Integer num : nums){
softAssert.assertTrue(num%2==0, String.format("\n Old num : %d", num);
}
softAssert.assertAll();
}
The above test will fail for numbers 1,3,5,7,9
Five statements will be printed in the test report.
If I run the test for a larger data set, I find it difficult to get the count of test data that failed the test case.
Is there any easier way to get the number of test data that failed for a test case using softAssert itself ?
Easy way to find count of test data that failed the test case in SoftAssert itself is not possible.
Alternatively you can think of extending Assertion class. Below is the sample that gives count of test data that failed the test case and prints each failure in new line.
package yourpackage;
import java.util.Map;
import org.testng.asserts.Assertion;
import org.testng.asserts.IAssert;
import org.testng.collections.Maps;
public class AssertionExtn extends Assertion {
private final Map<AssertionError, IAssert> m_errors;
public AssertionExtn(){
this.m_errors = Maps.newLinkedHashMap();
}
protected void doAssert(IAssert a) {
onBeforeAssert(a);
try {
a.doAssert();
onAssertSuccess(a);
} catch (AssertionError ex) {
onAssertFailure(a, ex);
this.m_errors.put(ex, a);
} finally {
onAfterAssert(a);
}
}
public void assertAll() {
if (!(this.m_errors.isEmpty())) {
StringBuilder sb = new StringBuilder("Total assertion failed: "+m_errors.size());
sb.append("\n\t");
sb.append("The following asserts failed:");
boolean first = true;
for (Map.Entry ae : this.m_errors.entrySet()) {
if (first)
first = false;
else {
sb.append(",");
}
sb.append("\n\t");
sb.append(((AssertionError)ae.getKey()).getMessage());
}
throw new AssertionError(sb.toString());
}
}
}
You can use this as:
#Test
public void test()
{
AssertionExtn asert=new AssertionExtn();
asert.assertEquals(false, true,"failed");
asert.assertEquals(false, false,"passed");
asert.assertEquals(0, 1,"brokedown");
asert.assertAll();
}

How to generalize a JMockit test using Spring autowiring

So I would like to use a generic test for a few different Dao methods. Inside the Dao, I implemented the save functionality to be Entity independent, so I figured it would be best to make the tests Entity independent as well. Currently I have the following for one of my jmockit tests that is autowired with spring.
#Injectable
public EntityManager em;
#Tested
SyncClaimDao syncClaimDao = new SyncClaimDaoImpl();
#Before
public void setUp() {
Deencapsulation.setField(syncClaimDao, "em", em);
}
private void testSaveEntity (Class T) {
// Existing claim happy path
new Expectations() {
{
em.contains(any); result = true;
em.merge(any);
}
};
if (T.isInstance(SyncClaimEntity.class)) {
Assert.assertTrue(syncClaimDao.saveClaim(new SyncClaimEntity()));
} else if (...) {...}
}
#Test
public void testSaveClaim() {
testSaveEntity(SyncClaimEntity.class);
}
SyncClaimDaoImpl
#Override
public boolean saveClaim(SyncClaimEntity claim) {
return saveEntity(claim);
}
private boolean saveEntity(Object entity) {
boolean isPersisted = false;
try {
isPersisted = em.contains(entity);
if (isPersisted) {
em.merge(entity);
} else {
em.persist(entity);
em.flush();
isPersisted = true;
}
logger.debug("Persisting " + entity.getClass().getSimpleName() + ": " + entity.toString());
}
catch (NullPointerException ex) {
...
}
catch (IllegalArgumentException ex) {
...
}
return isPersisted;
}
When I run the tests I am seeing the following errors:
mockit.internal.MissingInvocation: Missing invocation of:
javax.persistence.EntityManager#contains(Object)
with arguments: any Object
on mock instance: javax.persistence.$Impl_EntityManager#44022631
at at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
... 4 more
Caused by: Missing invocation
at [redacted].dal.dao.SyncClaimDaoImplTest$1.<init>(SyncClaimDaoImplTest.java:48)
at [redacted].dal.dao.SyncClaimDaoImplTest.testSaveEntity(SyncClaimDaoImplTest.java:46)
at [redacted].dal.dao.SyncClaimDaoImplTest.testSaveClaim(SyncClaimDaoImplTest.java:67)
... 10 more
Now if I just move the Expectations block into the #Test method like so:
#Test
public void testSaveClaim() {
new Expectations() {
{
em.contains(any); result = true;
em.merge(any);
}
};
Assert.assertTrue(syncClaimDao.saveClaim(new SyncClaimEntity()));
I get a successful test run as should be. I'm thinking that the spring autowiring for the Test method is not properly scoping my Expectations. That's why I'm seeing the missing invocation errors.
Does anyone have any ideas on how to generalize my Expectations so I can create simpler tests for generalized methods?
I see the mistake now: T.isInstance(SyncClaimEntity.class). The Class#isInstance(Object) method is supposed to be called with an instance of the class, not with the class itself; so, it's always returning false because SyncClaimEntity.class is obviously not an instance of SyncClaimEntity.

Spring JDBC and Java 8 - JDBCTemplate: retrieving SQL statement and parameters for debugging

I am using Spring JDBC and some nice Java 8 lambda-syntax to execute queries with the JDBCTemplate.
The reason for choosing Springs JDBCTemplate, is the implicit resource-handling that Spring-jdbc offers (I do NOT want a ORM framework for my simple usecase's).
My problem is that I want to debug the whole SQL statements with their parameters. Spring prints the SQL by default but not the parameters. Therefor I have subclassed the JDBCTemplate and overridden a query-method.
An example usage of the JDBCTemplate:
public List<Product> getProductsByModel(String modelName) {
List<Product> productList = jdbcTemplate.query(
"select * from product p, productmodel m " +
"where p.modelId = m.id " +
"and m.name = ?",
(rs, rowNum) -> new Product(
rs.getInt("id"),
rs.getString("stc_number"),
rs.getString("version"),
getModelById(rs.getInt("modelId")), // method not shown
rs.getString("displayName"),
rs.getString("imageUrl")
),
modelName);
return productList;
}
To get hold of the parameters I have, as mentioned, overridden the JDBCTemplate class. By doing a cast and using reflection I get the Object[] field with the parameters from an instance of ArgumentPreparedStatementSetter.
I suspect this implementation could potentially be dangerous, as the actual implementation of the PreparedStatementSetter may not always be ArgumentPreparedStatementSetter (Yes I should do an instanceOf check). Also, the reflection code may not be as elegant, but that is besides the point now though :).
Here's my custom implementation:
public class CustomJdbcTemplate extends JdbcTemplate {
private static final Logger log = LoggerFactory.getLogger(CustomJdbcTemplate.class);
public CustomJdbcTemplate(DataSource dataSource) {
super(dataSource);
}
public <T> T query(PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor<T> rse)
throws DataAccessException {
if(log.isDebugEnabled()) {
ArgumentPreparedStatementSetter aps = (ArgumentPreparedStatementSetter) pss;
try {
Field args = aps.getClass().getDeclaredField("args");
args.setAccessible(true);
Object[] parameters = (Object[]) args.get(aps);
log.debug("Parameters for SQL query: " + Arrays.toString(parameters));
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new GenericException(e.toString(), e);
}
}
return super.query(psc, pss, rse);
}
}
So, when I execute the log.debug(...) statement I would also like to have the original SQL query logged (same line). Has anyone done something similar or are there any better suggestions as to how this can be achieved?
I do quite a few queries using this CustomJDBCTemplate and all my tests run, so I think it may be an acceptable solution of for most debug purposes.
Kind regards,
Thomas
I found a way to get the SQL-statement, so I will answer my own question :)
The PreparedStatementCreator has the following implementation:
private static class SimplePreparedStatementCreator implements PreparedStatementCreator, SqlProvider
So the SqlProvider has a getSql() method which does exactly what I need.
Posting the "improved" CustomJdbcTemplate class if anyone ever should need to do the same :)
public class CustomJdbcTemplate extends JdbcTemplate {
private static final Logger log = LoggerFactory.getLogger(CustomJdbcTemplate.class);
public CustomJdbcTemplate(DataSource dataSource) {
super(dataSource);
}
public <T> T query(PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor<T> rse)
throws DataAccessException {
if(log.isDebugEnabled()) {
if(pss instanceof ArgumentPreparedStatementSetter) {
ArgumentPreparedStatementSetter aps = (ArgumentPreparedStatementSetter) pss;
try {
Field args = aps.getClass().getDeclaredField("args");
args.setAccessible(true);
Object[] parameters = (Object[]) args.get(aps);
log.debug("SQL query: [{}]\tParams: {} ", getSql(psc), Arrays.toString(parameters));
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new GenericException(e.toString(), e);
}
}
}
return super.query(psc, pss, rse);
}
private static String getSql(Object sqlProvider) { // this code is also found in the JDBCTemplate class
if (sqlProvider instanceof SqlProvider) {
return ((SqlProvider) sqlProvider).getSql();
}
else {
return null;
}
}
}