how to cover trigger in test class I am very new to slaesforce - testing

trigger contacttrigger on Contact (after insert, after delete, after undelete) {
Set<Id> Ids = new Set<Id>();
if(trigger.isInsert || trigger.isUndelete){
for(Contact con:trigger.new){
if(con.Id!= null){
Ids.add(con.Id);
} } }
if(trigger.isDelete){
for(Contact con:trigger.old){
if(con.Id!= null){
Ids.add(con.Id);
}}}
if(!Ids.isEmpty()){
List<Account> accList = [SELECT Id, NoOfContacts__c, (SELECT Id FROM Contacts) FROM Account WHERE Id IN : Ids];
if(!accList.isEmpty()){
List<Account> updateAccList = new List<Account>();
for(Account acc:accList){
Account objAcc = new Account(Id = acc.Id, NoOfContacts__c = acc.Contacts.size());
updateAccList.add(objAcc);
}
if(!updateAccList.isEmpty()){
update updateAccList;
}
}
}
}
hello every one I am very new to salesforce Please guide me how to cover this trigger in test class thank you

You must pick report message box "SQL report service system" another on mobile site.
Triggered as Reporting Monthly.
trigger contacttrigger on Contact (after insert, after delete, after undelete) { Set Ids = new Set(); if(trigger.isInsert || trigger.isUndelete){ for(Contact con:trigger.new){ if(con.Id!= null){ Ids.add(con.Id); } } } if(trigger.isDelete){ for(Contact con:trigger.old){ if(con.Id!= null){ Ids.add(con.Id); }}} if(!Ids.isEmpty()){ List accList = [SELECT Id, NoOfContacts__c, (SELECT Id FROM Contacts) FROM Account WHERE Id IN : Ids]; if(!accList.isEmpty()){ List updateAccList = new List(); for(Account acc:accList){ Account objAcc = new Account(Id = acc.Id, NoOfContacts__c = acc.Contacts.size()); updateAccList.add(objAcc); } if(!updateAccList.isEmpty()){ update updateAccList; } } } }

Related

How to send api request from test class to Main class in salesforce?

Class :
#RestResource(urlMapping='/api/fetch_status/*')
global class RestDemo{
#HttpGet
global static Account getResult(){
Account account;
String accountId = '';
RestRequest restReq = RestContext.request;
RestResponse restRes = RestContext.response;
// reading url
try{
//accountId = restReq.params.get('accountId');
accountId = restReq.requestURI.substring(restReq.requestURI.lastIndexOf('/') + 1);
account = [SELECT Id, Name FROM Account WHERE Id = :accountId Limit 1];
if(account != null){ //checked whether any record is returned or not
restRes.responseBody = Blob.valueOf(JSON.serialize(account));
restRes.statusCode = 200;
}else{
/* String account_not_found= '{"message":"Not Found"}';
restRes.responseBody = Blob.valueOf(account_not_found); */
restRes.statusCode = 404;
}
}
catch(Exception ex){
restRes.responseBody = Blob.valueOf(ex.getMessage());
restRes.statusCode = 500;
}
return account;
}
}
Test Class :
private class RestDemoTest {
#testSetup
static void dataSetup() {
Account acc = new Account(Name = 'Testing5');
insert acc;
}
static testMethod void testGet() {
//case 1 when the id is valid
Account acc = [ SELECT Id FROM Account LIMIT 1 ];
RestRequest req = new RestRequest();
RestResponse res = new RestResponse();
req.requestURI = '/services/apexrest/api/fetch_status/' + acc.Id;
req.httpMethod = 'GET';
RestContext.request = req;
RestContext.response= res;
Account acct1 = RestDemo.getResult();
system.assertEquals(acct1.Name, 'Testing5');
// case 2 when the id is not present
String str_id = '0012x000004UjZX';
Id id = Id.valueOf(str_id);
req.requestURI = '/services/apexrest/api/fetch_status/' + id;
req.httpMethod = 'GET';
RestContext.request = req;
RestContext.response= res;
Account acct2 = RestDemo.getResult();
system.assertEquals(acct2, null);
}
}
I want to test the test case 2 where the account with the random id is not present.
But while testing the test class (in test case 2 )it is giving exception.
In this i used an existing id and changed it a little.So while test case2 runs it should go through the else statement of the main class but it is throwing exception (catch statement,Tested it in salesforce developer console).
account = [SELECT Id, Name FROM Account WHERE Id = :accountId Limit 1];
The way you written it account will never be null. It'll just throw "List has no rows for assignment to SObject".
Change to this
List<Account> accs = [SELECT Id, Name FROM Account WHERE Id = :accountId Limit 1];
if(!accs.isEmpty()){
// return 200;
} else {
// return 400;
}
If you query that way it'll always come as List. It can be empty list but it will be a list (not null). Assign query results to single Account/Contact/... only if you're 100% sure it'll return something. Or catch the exceptions

How to create a apex test class for my apex class

It is my first apex class and i don't really know how to implement a proper test class.
My goal is to achieve test coverage of 75%.
I updated based on the comments but i managed to achieve only 70 %. I don't have other idea how to improve this more.
Here is what i did :
Apex class:
public with sharing class AccountController {
#AuraEnabled
public static List<Account> findAll() {
User userDetails =[SELECT Id, Name, Email, Profile.Name, UserRole.Name FROM User
where Id=:userinfo.getUserId() ];
// Theme4t is theme that is used by mobille app for android or iphone
if(((userDetails.UserRole.Name).equals('yon')|| (userDetails.UserRole.Name).equals('bon')|| (userDetails.UserRole.Name).contains('non')
|| (userDetails.UserRole.Name).contains('go')) && UserInfo.getUiTheme() != 'Theme4t'){
return [SELECT id, name, AccountStatus__c, ShippingLatitude, ShippingLongitude, ShippingCity
FROM Account
WHERE ShippingLatitude != NULL AND ShippingLongitude != NULL
LIMIT:22000];
}else {
return [SELECT id, name, AccountStatus__c, ShippingLatitude, ShippingLongitude, ShippingCity
FROM Account
WHERE OwnerId =: UserInfo.getUserId() AND ShippingLatitude != NULL AND ShippingLongitude != NULL
LIMIT:5000];
}
}
Apex test class:
#isTest
public class AccountControllerTest
{
static testMethod void testMethod1()
{
Account acc = new Account();
acc.Name='Test';
insert acc;
User userDetails =[SELECT Id, Name, Email, Profile.Name, UserRole.Name FROM User
where Id=:userinfo.getUserId() ];
List<Account> lstAcc = AccountController.findAll();
UserRole ur =new UserRole();
userDetails.UserRoleId=[select Id from UserRole where Name='yon'].Id;
System.runAs(userDetails){
List<Account> lstAcc1 = AccountController.findAll();
}
userDetails.UserRoleId=[select Id from UserRole where Name='bon'].Id;
System.runAs(userDetails){
List<Account> lstAcc2 = AccountController.findAll();
}
userDetails.UserRoleId=[select Id from UserRole where Name='non'].Id;
System.runAs(userDetails){
List<Account> lstAcc3 = AccountController.findAll();
}
userDetails.UserRoleId=[select Id from UserRole where Name='go'].Id;
System.runAs(userDetails){
List<Account> lstAcc4 = AccountController.findAll();
}
}
Please complete the below trailhead to learn the unit test in Salesforce.
https://trailhead.salesforce.com/en/content/learn/modules/apex_testing/apex_testing_intro
And also as you are trying to create a user after account insertion it will throw Mixed DML error. you need to use system.runAs() method. follow the below URL for using the method.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_tools_runas.htm
Let me know if still, you need any help on this.
Here is the code for your class and test class. Please follow the best practices from http://blog.shivanathd.com/2013/11/Best-Practices-Test-Class-in-Salesforce.html
This time I am providing the code to you to understand how to create a test class, but next time onwards please follow the steps and documents I have shared.
public with sharing class AccountController {
//using a test visible variable for setting the ui theme check.
#TestVisible static Boolean isTheme4t = UserInfo.getUiThemeDisplayed() == 'Theme4t';
#AuraEnabled
public static List<Account> findAll() {
User userDetails =[SELECT Id, Name, Email, Profile.Name, UserRole.Name FROM User where Id=:userinfo.getUserId()];
// Theme4t is theme that is used by mobille app for android or iphone
if(((userDetails.UserRole.Name).equals('yon')|| (userDetails.UserRole.Name).equals('bon')|| (userDetails.UserRole.Name).contains('non') || (userDetails.UserRole.Name).contains('go')) && !isTheme4t){
return [SELECT id, name, AccountStatus__c, ShippingLatitude, ShippingLongitude, ShippingCity FROM Account WHERE ShippingLatitude != NULL AND ShippingLongitude != NULL LIMIT 22000];
}else {
return [SELECT id, name, AccountStatus__c, ShippingLatitude, ShippingLongitude, ShippingCity FROM Account WHERE OwnerId =: UserInfo.getUserId() AND ShippingLatitude != NULL AND ShippingLongitude != NULL LIMIT 5000];
}
}
}
#isTest
public class AccountControllerTest
{
//Use setup data method to create data and query it in testmethod
#testSetup static void setup() {
UserRole r = new UserRole(DeveloperName = 'yon', Name = 'yon');
insert r;
User u = new User(
ProfileId = [SELECT Id FROM Profile WHERE Name = 'System Administrator'].Id,
LastName = 'last',
Email = 'puser000#amamama.com',
Username = 'puser000#amamama.com' + System.currentTimeMillis(),
CompanyName = 'TEST',
Title = 'title',
Alias = 'alias',
TimeZoneSidKey = 'America/Los_Angeles',
EmailEncodingKey = 'UTF-8',
LanguageLocaleKey = 'en_US',
LocaleSidKey = 'en_US',
UserRoleId = r.Id
);
insert u;
System.runAs(u){
Account acc = new Account();
acc.Name = 'Test Account';
acc.ShippingLatitude = 75.46;
acc.ShippingLongitude = 45.46;
acc.AccountStatus__c = 'test';
insert acc;
}
}
static testMethod void testMethod1(){
user u = [select Id from User where email = 'puser000#amamama.com' limit 1];
system.runAs(u){
Test.startTest();
List<Account> acc = [select Id,AccountStatus__c,ShippingLatitude,ShippingLongitude from Account where Name = 'Test Account'];
List<Account> lstAcc4 = AccountController.findAll();
system.assert(lstAcc4.size()>0);
Test.stopTest();
}
}
static testMethod void testMethod2(){
user u = [select Id from User where email = 'puser000#amamama.com' limit 1];
system.runAs(u){
AccountController.isTheme4t = true;
Test.startTest();
List<Account> acc = [select Id,AccountStatus__c,ShippingLatitude,ShippingLongitude from Account where Name = 'Test Account'];
List<Account> lstAcc4 = AccountController.findAll();
system.assert(lstAcc4.size()>0);
Test.stopTest();
}
}
}

Convert EntityFramework to Raw SQL Queries in MVC

I am trying to make a crud calendar in my .net, my question is, How do make the below entity framework codes to SQL queries?
[HttpPost]
public JsonResult SaveEvent(Event e)
{
var status = false;
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
if (e.EventID > 0)
{
//Update the event
var v = dc.Events.Where(a => a.EventID == e.EventID).FirstOrDefault();
if (v != null)
{
v.Subject = e.Subject;
v.Start = e.Start;
v.End = e.End;
v.Description = e.Description;
v.IsFullDay = e.IsFullDay;
v.ThemeColor = e.ThemeColor;
}
}
else
{
dc.Events.Add(e);
}
dc.SaveChanges();
status = true;
}
return new JsonResult { Data = new { status = status } };
}
http://www.dotnetawesome.com/2017/07/curd-operation-on-fullcalendar-in-aspnet-mvc.html
Thanks guys
You can run raw query in entity framework with dc.Database.ExecuteSqlCommand() command like below:
var status = false;
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
if (e.EventID > 0)
{
dc.Database.ExecuteSqlCommand(&#"
UPDATE Events
SET Subject = {e.Subject},
Start = {e.Start},
End = {End},
Description = {Description},
IsFullDay = {IsFullDay},
ThemeColor = {ThemeColor},
WHERE EventID = {e.EventID}
IF ##ROWCOUNT = 0
INSERT INTO Events (EventID, Subject, Start, End, Description, IsFullDay, ThemeColor)
VALUES ({e.EventID}, {e.Subject}, ...)
");
status = true;
}
return new JsonResult { Data = new { status = status }
};

How to rollback a transaction in EntityFramework?

I have two database tables named Courses and Transactions.Courses stores the details of a particular course and Transactions table stores the details of the transactions performed by a particular user.
My question is how can I make sure that entry in the CourseTable is saved only when transactions(add,edit,delete) regarding that particular course is saved into the TransactionTable
CourseTable is
TransactionTable is
Controller is
POST: /Course/Add
[HttpPost]
public ActionResult Add(CourseVM _mdlCourseVM)
{
string actionName=this.ControllerContext.RouteData.Values["action"].ToString();
string controllerName=this.ControllerContext.RouteData.Values["controller"].ToString();
Course _course = new Course();
_course.Duration = _mdlCourseVM.Course.Duration;
_course.DurationMode = _mdlCourseVM.DurationModeId;
_course.InstalmentFee = _mdlCourseVM.Course.InstalmentFee;
_course.Name = _mdlCourseVM.Course.Name;
_course.SingleFee = _mdlCourseVM.Course.SingleFee;
_db.Courses.Add(_course);
int i = _db.SaveChanges();
if (i > 0)
{
Common _cmn=new Common();
//Add the transaction details
int k=_cmn.AddTransactions(actionName,controllerName,"");
//Want to commit changes to the coursetable here
if(k>0){
_db.commitTransaction()
}
//Want to rollback the committed transaction
else{
_db.rollbackTransaction();
}
}
}
I solved the above scenario by using System.Transactions.Hope anyone with same scenario find it useful.
using (TransactionScope _ts = new TransactionScope())
{
string actionName = this.ControllerContext.RouteData.Values["action"].ToString();
string controllerName = this.ControllerContext.RouteData.Values["controller"].ToString();
Course _course = new Course();
_course.Duration = _mdlCourseVM.Course.Duration;
_course.DurationMode = _mdlCourseVM.DurationModeId;
_course.InstalmentFee = _mdlCourseVM.Course.InstalmentFee;
_course.Name = _mdlCourseVM.Course.Name;
_course.SingleFee = _mdlCourseVM.Course.SingleFee;
_db.Courses.Add(_course);
int i = _db.SaveChanges();
if (i > 0)
{
Common _cmn = new Common();
int k = _cmn.AddTransactions(actionName, controllerName, "",Session["UserId"].ToString());
if (k > 0)
{
_ts.Complete();
return Json(new { message = "success" }, JsonRequestBehavior.AllowGet);
}
else
{
return Json(new { message = "error" }, JsonRequestBehavior.AllowGet);
}
}
else
{
return Json(new { message = "error" }, JsonRequestBehavior.AllowGet);
}
}
}

Existing posts keep on re-add upon deletion of selected row in jTable

I try to refresh the data of jTable upon deletion of selected row. Here are my codes to set up table :
private JTable getJTableManageReplies() {
jTableManageReplies.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jTableManageReplies.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
int viewRow = jTableManageReplies.getSelectedRow();
// Get the first column data of the selectedrow
int replyID = Integer.parseInt(jTableManageReplies.getValueAt(
viewRow, 0).toString());
eForumRepliesAdmin reply = new eForumRepliesAdmin(replyID);
replyID = JOptionPane.showConfirmDialog(null, "Are you sure that you want to delete the selected reply? " , "Delete replies", JOptionPane.YES_NO_OPTION);
if(replyID == JOptionPane.YES_OPTION){
reply.deleteReply();
JOptionPane.showMessageDialog(null, "Reply has been deleted successfully.");
SetUpJTableManageReplies();
}
}
}
});
return jTableManageReplies;
}
public void SetUpJTableManageReplies() {
DefaultTableModel tableModel = (DefaultTableModel) jTableManageReplies
.getModel();
String[] data = new String[5];
db.setUp("IT Innovation Project");
String sql = "Select forumReplies.reply_ID,forumReplies.reply_topic,forumTopics.topic_title,forumReplies.reply_content,forumReplies.reply_by from forumReplies,forumTopics WHERE forumReplies.reply_topic = forumTopics.topic_id ";
ResultSet resultSet = null;
resultSet = db.readRequest(sql);
jTableManageReplies.repaint();
tableModel.getDataVector().removeAllElements();
try {
while (resultSet.next()) {
data[0] = resultSet.getString("reply_ID");
data[1] = resultSet.getString("reply_topic");
data[2] = resultSet.getString("topic_title");
data[3] = resultSet.getString("reply_content");
data[4] = resultSet.getString("reply_by");
tableModel.addRow(data);
}
resultSet.close();
} catch (Exception e) {
System.out.println(e);
}
}
And this is my sql statement :
public boolean deleteReply() {
boolean success = false;
DBController db = new DBController();
db.setUp("IT Innovation Project");
String sql = "DELETE FROM forumReplies where reply_ID = " + replyID
+ "";
if (db.updateRequest(sql) == 1)
success = true;
db.terminate();
return success;
}
I called the repaint() to update the table data with the newest data in database and it works. I mean the data after deletion of certain row. However, the existing posts will keep on re-add. Then I add the removeAllElement method to remove all the existing posts because my sql statement is select * from table. Then, there is an error message which is ArrayIndexOutOfBoundsException. Any guides to fix this? Thanks in advance.
I called the repaint() to update the table data with the newest data
in database and it works.
There is no need to call repaint method when data is changed. Data change is handled by the Table Model (DefaultTableModel in this case.) And fireXXXMethods are required to be called whenever data is changed but you are using DefaultTableModel even those are not required. (Since by default it call these methods when ever there is a change.)
I think the problem is in the valuesChanged(..) method. You are getting the value at row 0 but not checking whether table has rows or not. So keep a constraint.
int viewRow = jTableManageReplies.getSelectedRow();
// Get the first column data of the selectedrow
if(jTableManageReplies.getRowCount() > 0)
int replyID = Integer.parseInt(jTableManageReplies.getValueAt(viewRow, 0).toString());