I am trying to test with EasyMock the service layer by mocking the DAO.
One of the methods in my DAO class is shown below.
public BrickStreamUserVO getUserDetails(String userName, String password)
{
BrickStreamUserVO usrObj = null;
try
{
String sqlStr = "SELECT * FROM USER_T WHERE USER_NAME LIKE '" + userName + "'
AND PASSWORD = '" + password + "'";
usrObj = getJdbcTemplate().queryForObject(sqlStr, new BrickStreamUserMapper());
logger.info("Getting user details....");
if(usrObj==null)
throw new UserException("Invalid Login parameters");
}
catch (Exception e)
{
logger.error(e);
throw new UserException("Invalid Login parameters");
}
return usrObj;
}
And here is my test code
public class BrickStreamServiceImplTest
{
private BrickStreamServiceImpl serviceImpl;
#Before
public void buildService()
{
serviceImpl = new BrickStreamServiceImpl();
}
#Test
public void testGetUserDetails()
{
BrickStreamDaoImpl daoImplMock = createMock(BrickStreamDaoImpl.class);
expect(daoImplMock.getUserDetails("user", "pwd")).
andReturn(new BrickStreamUserVO());
replay(daoImplMock);
serviceImpl.setBrickStreamDao(daoImplMock);
serviceImpl.getUserDetails("user", "pwd");
verify(daoImplMock);
}
}
How can I test the method to throw the UserException, you can see that if the usrObj object is null it throws a UserException.
If you mock the getUserDetails method, you won't be able to test its behavior.
You may want to extract a method where you do the user query, and mock it.
public BrickStreamUserVO queryForUser(String userName, String password) {
String sqlStr = "SELECT * FROM USER_T WHERE USER_NAME LIKE '" + userName + "'
AND PASSWORD = '" + password + "'";
return getJdbcTemplate().queryForObject(sqlStr, new BrickStreamUserMapper());
}
public BrickStreamUserVO getUserDetails(String userName, String password)
{
BrickStreamUserVO usrObj = null;
try
{
usrObj = queryForUser(userName, password);
logger.info("Getting user details....");
if(usrObj==null) {
throw new UserException("Invalid Login parameters");
}
} catch (Exception e) {
logger.error(e);
throw new UserException("Invalid Login parameters");
}
return usrObj;
}
In your test class :
#Test(expected = UserException.class)
public void testGetUserDetails()
{
BrickStreamDaoImpl daoImplMock = createMockBuilder(BrickStreamDaoImpl.class).addMockedMethod("queryForUser").createMock();
expect(daoImplMock.queryForUser("user", "pwd")).andReturn(null);
replay(daoImplMock);
serviceImpl.setBrickStreamDao(daoImplMock);
serviceImpl.getUserDetails("user", "pwd");
}
Related
I have all my tests pass except this line in the first test
verify(reimbursementDAO).getById(REIMBURSEMENT_TO_PROCESS.getId());
see code below.
package com.revature.services;
public class ReimbursementServiceTest {
private static ReimbursementService reimbursementService;
private static ReimbursementDAO reimbursementDAO;
private Reimbursement REIMBURSEMENT_TO_PROCESS;
private Reimbursement GENERIC_REIMBURSEMENT_1;
private Optional<Reimbursement>
GENERIC_REIMBURSEMENT_2;
private List<Reimbursement> GENERIC_ALL_PENDING_REIMBURSEMENTS;
private User GENERIC_EMPLOYEE_1;
private User GENERIC_FINANCE_MANAGER_1;
#BeforeClass
public static void setUpBeforeClass() throws Exception {
reimbursementDAO=mock(ReimbursementDAO.class);//(IReimbursementDAO.class);
reimbursementService = new ReimbursementService(reimbursementDAO);
//reimbursementDAO=new ReimbursementDAO();
}
#Before
public void setUp() throws Exception {
GENERIC_EMPLOYEE_1 = new User(1, "genericEmployee1", "genericPassword", Role.EMPLOYEE);
GENERIC_FINANCE_MANAGER_1 = new User(1, "genericManager1", "genericPassword", Role.FINANCE_MANAGER);
REIMBURSEMENT_TO_PROCESS = new Reimbursement(2, Status.PENDING, GENERIC_EMPLOYEE_1, null, 150.00);
GENERIC_REIMBURSEMENT_1 = new Reimbursement(1, Status.PENDING, GENERIC_EMPLOYEE_1, null, 100.00);
GENERIC_REIMBURSEMENT_2 = Optional.ofNullable(new Reimbursement(2, Status.APPROVED, GENERIC_EMPLOYEE_1,
GENERIC_FINANCE_MANAGER_1, 150.00));
GENERIC_ALL_PENDING_REIMBURSEMENTS = new ArrayList<Reimbursement>();
GENERIC_ALL_PENDING_REIMBURSEMENTS.add(GENERIC_REIMBURSEMENT_1);
}
#Test
public void testProcessPassesWhenUserIsFinanceManagerAndReimbursementExistsAndUpdateSuccessful()
throws Exception{
when(reimbursementDAO.getById(anyInt())).thenReturn(Optional.of(GENERIC_REIMBURSEMENT_1));
when(reimbursementDAO.update(any())).thenReturn(GENERIC_REIMBURSEMENT_2);
assertEquals(GENERIC_REIMBURSEMENT_2,
reimbursementService.process(REIMBURSEMENT_TO_PROCESS, Status.APPROVED,
GENERIC_FINANCE_MANAGER_1));
//verify(reimbursementDAO).getById(REIMBURSEMENT_TO_PROCESS.getId());
verify(reimbursementDAO).update(REIMBURSEMENT_TO_PROCESS);
}
#Test
public void testGetReimbursementByStatusPassesWhenReimbursementsAreSuccessfullyReturned() {
when(reimbursementDAO.getBystatus(any())).thenReturn(GENERIC_ALL_PENDING_REIMBURSEMENTS);
assertEquals(GENERIC_ALL_PENDING_REIMBURSEMENTS,
reimbursementService.getReimbursementsByStatus(Status.PENDING));
verify(reimbursementDAO).getBystatus(Status.PENDING);
}
}
public class ReimbursementDAO extends AbstractReimbursement
{
public Optional< Reimbursement> getById(int id) {
try(Connection conn = ConnectionFactory.getConnection())
{
String sql="select * from ers_reimbursements where reimb_id=?;";
PreparedStatement ps=conn.prepareStatement(sql);
ps.setInt(1,id);
ResultSet rs= ps.executeQuery();
Reimbursement reimb=null;
UserService usrv=new UserService();
//reimb_id ,amount, submitted,resolved,description,author,receipt ,resolver,status,reimb_type
while(rs.next())
{
int reid=rs.getInt("reimb_id");
double ramount=rs.getInt("reimb_amount");
int res=rs.getInt( "resolver");
User resolver=null;
String description=rs.getString("description");
User rauthor= usrv.getUserById( rs.getInt("author")).get();
if(res>0)
{ resolver= usrv.getUserById(res).get(); }
int rstatus= rs.getInt("reimb_status");
Status r_status=Status.values()[--rstatus];
int reimb_type= rs.getInt("reimb_type");
ReimbType retype=ReimbType.values()[--reimb_type];
User oth=rauthor;
User re=resolver;
reimb=new Reimbursement(reid, r_status,oth,re,ramount);
return Optional.ofNullable(reimb);
}
}catch(SQLException e) { e.printStackTrace();};
return Optional.empty();
}
public List<Reimbursement> getBystatus(Status status) {
try(Connection conn = ConnectionFactory.getConnection())
{
String sql="select * from ers_reimbursements where reimb_status=?;";
PreparedStatement ps=conn.prepareStatement(sql);//,Statement.RETURN_GENERATED_KEYS);
int sta_id= status.ordinal()+1;
ps.setInt(1,sta_id);
ResultSet rs= ps.executeQuery();
Reimbursement reimb=null;
List<Reimbursement> reimbList=new ArrayList<Reimbursement>();
IUserService usrv=new UserService();
//reimb_id ,amount, submitted,resolved,description,author,receipt ,resolver,status,reimb_type
while(rs.next())
{
//int id, Status status, User author, User resolver, double amount
int reid=rs.getInt("reimb_id");
double ramount=rs.getInt("reimb_amount");
Optional<User> rauthor= usrv.getUserById( rs.getInt("author"));
User oth=null;
if(rauthor.isPresent())
{ oth=rauthor.get(); }
int resol=rs.getInt( "resolver");
Optional<User> resolver= usrv.getUserById(resol);
User re=null;
if(resolver.isPresent())
{ re=resolver.get(); }
else {re=null;}
int rstatus= rs.getInt("reimb_status");
Status r_status=Status.values()[--rstatus];//.PENDING;
int reimb_type= rs.getInt("reimb_type");
ReimbType retype=ReimbType.values()[--reimb_type];//.TRAVEL;
reimb=new Reimbursement(reid, r_status,oth,re,ramount);
reimbList.add(reimb);
}
return reimbList;
}catch(SQLException e) { e.printStackTrace();};
return null;
}
public Optional<Reimbursement> update(Reimbursement unprocessedReimbursement) {
try(Connection conn=ConnectionFactory.getConnection()) {
String sql="update ers_reimbursements set reimb_status=?,"
+ " resolver=?, resolved=? where reimb_id=?;";
PreparedStatement ps=conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
int id=unprocessedReimbursement.getId();
Status st=unprocessedReimbursement.getStatus();
ps.setObject(1,st);
ps.setInt(2,unprocessedReimbursement.getResolver().getId());
ps.setObject(3, LocalDateTime.now());
ps.setInt(4,id);
ps.executeUpdate();
try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
if (generatedKeys.next()) {
int reimid=generatedKeys.getInt(1);
Optional<Reimbursement> reim=getById(reimid);
System.out.println("Reimb " + reim.get()+ " upLocalTimed!");
return reim;
}
}catch(SQLException e) {};
}catch(SQLException e) { e.printStackTrace();}
return Optional.empty();
}
}
public class ReimbursementService{
{
private final ReimbursementDAO reimbDao;
public ReimbursementService() {
this(new ReimbursementDAO());
}
public ReimbursementService(ReimbursementDAO userDAO2) {
this.reimbDao = userDAO2;
}
public Optional< Reimbursement> process(Reimbursement unprocessedReimbursement,
Status finalStatus, User resolver) throws Exception{
if (!resolver.getRole().equals(Role.FINANCE_MANAGER)) {
throw new RegistrationUnsuccessfulException("Resolver must be Finance Manager ");
}
// List<Reimbursement> l=DAO.getByStatus(Status.PENDING);
if(unprocessedReimbursement.getId()==0)
{ throw new Exception(" reimbursement not found"); }
if(unprocessedReimbursement.getStatus().equals(Status.PENDING))
{
unprocessedReimbursement.setResolver(resolver);
unprocessedReimbursement.setStatus(finalStatus);
Optional<Reimbursement> reimb=this.reimbDao.update(unprocessedReimbursement );
if(reimb.isPresent())
{ return reimb; }
else { throw new Exception("unsuccessful update");}
}
return Optional.ofNullable(null);
}
}
The verification
verify(reimbursementDAO).getById(REIMBURSEMENT_TO_PROCESS.getId());
fails because your service does not call the getById() method of your DAO.
It happens that your real DAO's update() method calls its own getById() method, but in your test you are using a mock DAO, where all functionality has been stubbed out. The update() method of the mock DAO does nothing more than return GENERIC_REIMBURSEMENT_2 because that's what your test sets it up to do.
I am using Postman to test an ASP.Net web api 2 application that I created using I created using VS 2017.
It uses ADO.Net to call stored procedures. I tested the stored procedures and they work fine. I created a console app to test the methods and they work fine.
The URL that returns a model object works fine.
http://localhost:56224/api/profileandblog/getactiveuser/2020-03-03/DancinDan/32.211.50.62/1
The URL that returns a boolean does not. I get Error - 404.0 - Not Found
http://localhost:56224/api/profileandblog/validatelogin/2020-03-03/DancinDan/Morewealth1/32.211.50.62
Here is the dataaccesslayer.cs in my Models folder:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using GbngWebApi2.ADO_Utilities;
namespace GbngWebApi2.Models
{
public class DataAccessLayer
{
DatabaseFunctions dbFunc = new DatabaseFunctions();
public bool ValidateLogin(DateTime currentDateTime, string userName, string userPassword, string ipAddress)
{
bool returnedStatus = false;
try
{
dbFunc.OpenDB();
SqlCommand cmd = new SqlCommand("dbo.ValidateLogin", dbFunc.objConn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#a_CurrentDateTime", currentDateTime);
cmd.Parameters.AddWithValue("#a_UserName", userName);
cmd.Parameters.AddWithValue("#a_UserPassword", userPassword);
cmd.Parameters.AddWithValue("#a_IpAddress", ipAddress);
// Set the OUT parameter.
cmd.Parameters.Add("#a_PasswordStatusSwitchOut", SqlDbType.Bit);
cmd.Parameters["#a_PasswordStatusSwitchOut"].Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
// Get the value from the OUT parameter.
// Cast to Boolean.
returnedStatus = (bool)cmd.Parameters["#a_PasswordStatusSwitchOut"].Value;
return returnedStatus;
}
catch (SqlException sqlex)
{
throw sqlex;
}
catch (Exception ex)
{
throw ex;
}
finally
{
dbFunc.CloseDB();
}
}
public User GetActiveUser(DateTime currentDateTime, string userName, string ipAddress, int userId)
{
User user = new User();
SqlDataReader userDataReader = null;
try
{
dbFunc.OpenDB();
SqlCommand cmd = new SqlCommand("dbo.GetActiveUser", dbFunc.objConn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#a_CurrentDateTime", currentDateTime);
cmd.Parameters.AddWithValue("#a_UserName", userName);
cmd.Parameters.AddWithValue("#a_IpAddress", ipAddress);
cmd.Parameters.AddWithValue("#a_UserId", userId);
userDataReader = cmd.ExecuteReader();
while (userDataReader.Read())
{
user.UserId = Convert.ToInt32(userDataReader["UserId"]);
user.UserName = userDataReader["UserName"].ToString();
user.ActiveSwitch = Convert.ToInt32(userDataReader["ActiveSwitch"]);
user.ApiAccessSwitch = Convert.ToInt32(userDataReader["ApiAccessSwitch"]);
user.AdminSwitch = Convert.ToInt32(userDataReader["AdminSwitch"]);
user.BlogAuthorSwitch = Convert.ToInt32(userDataReader["BlogAuthorSwitch"]);
user.BlogUserName = userDataReader["BlogUserName"].ToString();
user.IpAddress = userDataReader["IpAddress"].ToString();
user.IpAddressUsedForRegisteringCount = Convert.ToInt32(userDataReader["IpAddressUsedForRegisteringCount"]);
user.LoginCount = Convert.ToInt32(userDataReader["LoginCount"]);
user.ModifiedCount = Convert.ToInt32(userDataReader["ModifiedCount"]);
user.SuggestionCount = Convert.ToInt32(userDataReader["SuggestionCount"]);
user.SelectedForPublicViewSwitch = Convert.ToInt32(userDataReader["SelectedForPublicViewSwitch"]);
user.ModifiedDateTime = Convert.ToDateTime(userDataReader["ModifiedDateTime"]);
user.CreatedDateTime = Convert.ToDateTime(userDataReader["CreatedDateTime"]);
}
return user;
}
catch (SqlException sqlex)
{
throw sqlex;
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (userDataReader != null)
{
userDataReader.Close();
}
dbFunc.CloseDB();
}
}
}
}
Here is the WebApi2Controller:
using System;
using System.Web.Http;
using GbngWebApi2.Models;
namespace GbngWebApi2.Controllers
{
[RoutePrefix("api/profileandblog")]
public class WebApi2Controller : ApiController
{
DataAccessLayer dataaccesslayer = new DataAccessLayer();
[HttpGet]
[Route("validatelogin/{currentDateTime}/{userName}/{userPassword}/{ipAddress}")]
public bool ValidateLogin(DateTime currentDateTime, string userName, string userPassword, string ipAddress)
{
try
{
// Returns a boolean indicator of success or failure.
return dataaccesslayer.ValidateLogin(currentDateTime, userName, userPassword, ipAddress);
}
catch (Exception)
{
throw;
}
}
[HttpGet]
[Route("getactiveuser/{currentDateTime}/{userName}/{ipAddress}/{userId}")]
public User GetActiveUser(DateTime currentDateTime, string userName, string ipAddress, int userId)
{
try
{
// Returns the active "user" from the database.
return dataaccesslayer.GetActiveUser(currentDateTime, userName, ipAddress, userId);
}
catch (Exception)
{
throw;
}
}
}
}
From Nkosi: Add a slash at the end and it will work /32.211.50.62/
I am a new for JSP and I dont know any information about connection of oracle with JSP can anyone help me step by step?
You have to look at JDBC for Oracle. Using Java of course, not JSP.
This is a very basic Database class I used to use for very little projects.
public class Database {
private String driverName = "oracle.jdbc.driver.OracleDriver";
private Connection conn;
public static Hashtable errors = null;
public Database(String serverName, String portNumber, String serviceName, String username, String password, String db) {
errors = new Hashtable();
try {
String url = "jdbc:oracle:thin:#" + serverName + ":" + portNumber + ":" + serviceName;
Class.forName(driverName);
this.conn = DriverManager.getConnection(url, username, password);
} catch (Exception e) {
System.out.println(e);
errors.put(db, e);
}
}
public Connection getConnection(){
return this.conn;
}
}
here is a sample of a query
Database db = new Database(......); // see Database class construct
try {
java.sql.Statement st = db.getConnection().createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM FOO");
while(rs.next()){
// your code
}
rs.close();
st.close();
} catch (SQLException ex) {
Logger.getLogger(Table.class.getName()).log(Level.SEVERE, null, ex);
}
hope this helps :)
Suppose we have this code for login & we want if the credential was for admin page the RequestMapping be for admin & if it was for user credential the user redirect to user panel.
now, the main page of both oppose the same url as I defined in my code below, something like :
http://localhost:8080/project/{username}/main
my question is :
how we can separate these two method in here when they have the same RequestMapping "main" after the login checking finished inside the Controller class?
#RequestMapping(value = "/login")
public String welcome(#RequestParam("j_username") String username, #RequestParam("j_password") String password, HttpSession session, Model model) throws RemoteException, NotBoundException {
int checkAccount = uiClient.checkAdminAccount(username, password);
if (checkAccount == 1) {
session.setAttribute("username", username);
return "redirect:/" + username + "/main";
} else if (checkAccount == 0) {
checkAccount = uiClient.checkAccount(username, password);
if (checkAccount == 1) {
session.setAttribute("username", username);
return "redirect:/" + username + "/main";
} else if (checkAccount == 0) {
return "login";
}
} else {
return "databaseError";
}
return "login";
}
#RequestMapping(value = "/{username}/main")
public String indexPage(#PathVariable("username") String username) {
return "/user/userPanel";
}
#RequestMapping(value = "{username}/main")
public String adminIndexPage(#PathVariable("username") String username){
return "/admin/adminPanel";
}
I mean, is there any way like special tag or something that we can put for each Mapping & separate them after the login process finished so the admin redirect to adminPanel & the user also redirect to userPanel but both with the same url:
http://localhost:8080/project/{username}/main
???
What about this way:
#RequestMapping(value = "/login")
public String welcome(#RequestParam("j_username") String username, #RequestParam("j_password") String password, HttpSession session, Model model) throws RemoteException, NotBoundException {
int checkAccount = uiClient.checkAdminAccount(username, password);
if (checkAccount == 1) {
session.setAttribute("username", username);
session.setAttribute("userrole", "Admin");
return "redirect:/" + username + "/main";
} else if (checkAccount == 0) {
checkAccount = uiClient.checkAccount(username, password);
if (checkAccount == 1) {
session.setAttribute("username", username);
session.setAttribute("userrole", "Admin");
return "redirect:/" + username + "/main";
} else if (checkAccount == 0) {
return "login";
}
} else {
return "databaseError";
}
return "login";
}
#RequestMapping(value = "/{username}/main")
public String indexPage(#PathVariable("username") String username) {
if ("Admin".equals(session.getAttribute("userrole"))) {
return "/admin/adminPanel";
} else {
return "/user/userPanel";
}
}
For simplicity, I didn't use Spring Security to check user role here.
I have a class that have three methods that have functionalities on Active Directory. Here is the class:
[Export(typeof(IAuthentication))]
public class Authentication : IAuthentication
{
public bool Authenticate(string domain, string username, string password)
{
try
{
using (PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, domain, string.Empty))
{
return principalContext.ValidateCredentials(
username,
password,
ContextOptions.SimpleBind);
}
}
catch (Exception ex)
{
throw ex;
}
}
public UserPrincipal GetUserDetails(string domain, string username)
{
try
{
using (PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, domain))
{
return UserPrincipal.FindByIdentity(principalContext, username);
}
}
catch (Exception ex)
{
throw ex;
}
}
public PrincipalSearchResult<Principal> SearchUsers(string domain, string firstName, string lastName, string userName)
{
try
{
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domain))
{
UserPrincipal user = new UserPrincipal(ctx);
user.Enabled = true;
user.Name = firstName + "* " + lastName + "*";
user.SamAccountName = userName + "*";
PrincipalSearcher principalSearcher = new PrincipalSearcher();
principalSearcher.QueryFilter = user;
return principalSearcher.FindAll();
}
}
catch (Exception ex)
{
throw ex;
}
}
}
As you see in the class attribute, I'm using this class library as a MEF plugin. In my asp.net mvc 3 application, I call the method like this:
PrincipalSearchResult<Principal> results = _authentication.SearchUsers(
ConfigurationManager.AppSettings["DomainName"],
model.UserSearchCriteria.FirstName,
model.UserSearchCriteria.LastName,
model.UserSearchCriteria.Username);
But after I intend to use the return value of the method, I'm getting Cannot access a disposed object, Object name: 'PrincipalContext' exception. I know I'm disposing the PrincipalContext object but if I do not, the connection to the Active Directory will stay open. I think the design of my class is not correct. How can I make it work in a cool way?
I would imagine that when you eventually enumerate over the instance of PrincipalSearchResult<T>, this deferred operation is trying to access the context, which has since been closed. In this scenario, it is likely better for you to enumerate over the results straight away and return them as domain-specific models. I.e, do the work at the time, and not defer it through returning PrincipalSearchResult<T>.