This is a very basic problem, but I cannot seem to solve/figure out the problem so hoping some fresh eyes can help out.
I have a model User which has username and password. I want to allow Users to update their password, so I added update() method as shown below:
public static void update(User user) throws UserException {
User record = User.getById(user.id);
if (null == record) {
throw new UserException(BaseException.invalidRecordMessageException(User.class.getSimpleName()));
}
if (!StringUtils.equals(record.username, user.username)) {
throw new UserException(BaseException.unmodifiableFieldMessageException(User.class.getSimpleName(), "username"));
}
validatePassword(user.password);
saveUser(user);
}
And here is my saveUser():
private static void saveUser(User user) {
user.password = encryptPassword(user.password);
user.save();
System.out.println("n: " + user.id);
System.out.println("n: " + user.username);
System.out.println("n: " + user.password);
User r = User.getById(user.id);
System.out.println("r: " + r.id);
System.out.println("r: " + r.username);
System.out.println("r: " + r.password);
}
I added a test to confirm that the functionality is working perfectly.
#Test
public void testUpdateUserPasswordWithValidPasswordShouldUpdateRecord() {
try {
User dummy = new User(DEFAULT_USERNAME, DEFAULT_RAW_PASSWORD);
User.create(dummy);
assertNotNull(dummy.id);
User record = User.getById(dummy.id);
assertEquals(DEFAULT_USERNAME, record.username);
assertEquals(DEFAULT_RAW_PASSWORD, record.password);
dummy.password = DEFAULT_RAW_PASSWORD + "_extra";
User.update(dummy);
User updatedRecord = User.getById(dummy.id);
assertEquals(dummy.username, updatedRecord.username);
assertEquals(dummy.password, updatedRecord.password);
} catch (UserException ue) {
fail("Test should not throw exception.");
}
}
However, the test is failing as the record does not seem to be updating:
Test UserTest.testUpdateUserPasswordWithValidPasswordShouldUpdateRecord failed: expected:<$uP3rsecretpassword[_extra]> but was:<$uP3rsecretpassword[]>
DEFAULT_PASSWORD = $uP3rsecretpassword
Here is the output of all System.out.println() calls:
--- initial create ---
n: 1
n: moo
n: $uP3rsecretpassword
r: 1
r: moo
r: $uP3rsecretpassword
--- update ---
n: 1
n: moo
n: $uP3rsecretpassword_extra
r: 1
r: moo
r: $uP3rsecretpassword
Thanks in advance to any help.
I believe the problem lies in this line:
User record = User.getById(user.id);
Hibernate only keeps around one object of a certain id. So, here, you're effectively overwriting the change which is contained in the object user with the (old) state currently in the DB.
As for the checks you're doing there, they seem to be a bit superfluous anyways as you're not trusting your own code.
Related
I am automating e-commerce website. I am using JUNIT-Selenium framework.
Their are two files i am working with, first is the "TestCase.java" where my test steps are mentioned, aslo to start automation i run this file and second file is "TestMain.java" which has validation methods which will used by First file to verify and input the data in UI (mostly using If ..else validation).
First file consist of Automation initiation code, which uses Hashmap for reading the excel, extent report initiation and flush and use methods from testMain.java for input of data and validation through if... else statement.
TestCase.java looks like this:
public class TestCase extends AppTest {
private StringBuffer verificationErrors = new StringBuffer();
#Override
#Before
public void setUp() throws Exception {
super.setUp();
preparation = new Prep();
application = new AppToTest();
user = new Environment();
}
#Test
public void testLAP_Creamix() throws Exception {
try {
launchMainApplication();
Test_frMain Test_frMainPage = new Test_frMain(tool, test, user, application);
HashMap<String, ArrayList<String>> win = CreamixWindowsDataset.main();
SortedSet<String> keys = new TreeSet<>(win.keySet());
ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter("Test_Report.html");
ExtentReports extent = new ExtentReports();
extent.attachReporter(htmlReporter);
ExtentTest test1 = extent.createTest("Creamix test");
for (String i : keys) {
System.out.println("########### Test = " + win.get(i).get(0) + " ###########");
Lapeyre_frMainPage.EnterTaille(win.get(i).get(1));
Lapeyre_frMainPage.SelectCONFIGURATION(win.get(i).get(2));
Lapeyre_frMainPage.SelectPLANVASQUE(win.get(i).get(3));
Lapeyre_frMainPage.SelectCOULEUR(win.get(i).get(4));
Lapeyre_frMainPage.SelectPOIGNEES(win.get(i).get(5));
Lapeyre_frMainPage.SelectTYPE_DE_MEUBLE(win.get(i).get(6));
Lapeyre_frMainPage.SelectCHOISISSEZ(win.get(i).get(7));
Lapeyre_frMainPage.VerifyREFERENCE(win.get(i).get(8));(FROM HERE Validation Starts)
Lapeyre_frMainPage.VerifyQUANTITY(win.get(i).get(9));
Lapeyre_frMainPage.VerifyREFERENCETwo(win.get(i).get(10));
Lapeyre_frMainPage.VerifyQUANTITYTwo(win.get(i).get(11));
Lapeyre_frMainPage.VerifyREFERENCEThree(win.get(i).get(12));
Lapeyre_frMainPage.VerifyQUANTITYThree(win.get(i).get(13));
Lapeyre_frMainPage.VerifyREFERENCEFour(win.get(i).get(14));
Lapeyre_frMainPage.VerifyQUANTITYFour(win.get(i).get(15));
Lapeyre_frMainPage.VerifyREFERENCEFive(win.get(i).get(16));
Lapeyre_frMainPage.VerifyQUANTITYFive(win.get(i).get(17));
Lapeyre_frMainPage.VerifyREFERENCESix(win.get(i).get(18));
Lapeyre_frMainPage.VerifyQUANTITYSix(win.get(i).get(19));
Lapeyre_frMainPage.VerifyREFERENCESeven(win.get(i).get(20));
Lapeyre_frMainPage.VerifyQUANTITYSeven(win.get(i).get(21));
Lapeyre_frMainPage.VerifyPanierPrice(win.get(i).get(22));
Lapeyre_frMainPage.VerifyECO_PARTPrice(win.get(i).get(23));
Lapeyre_frMainPage.ClickCREAMIXReinit();(Reset button to test next scenario)
test1.pass("Scenario " + win.get(i).get(0) + " is passed");
System.out.println("########### Test End ##############");
extent.flush();----------(Extent report over)
}
test.setResult("pass");
} catch (AlreadyRunException e) {
} catch (Exception e) {
verificationErrors.append(e.getMessage());
throw e;
}
}
#Override
#After
public void tearDown() throws Exception {
super.tearDown();
}
}
(Please note one loop is one scenario where im customizing and validating price of the product and then clicking reset button to next scenario for doing same)
And,
"TestMain.java" from where i am using methods to validate
one of the method is shown below
public void VerifyREFERENCE(String REF_1) throws Exception {
System.out.println("Verifying reference article");
if (REF_1.equals("SKIP")) {
System.out.println("SKIPPED");
} else {
WebElement referenceOne = tool.searchUsingXPath("//tbody//tr[1]//td//div[2]");
String Ref1 = referenceOne.getText().trim();
System.out.println("ref 1 is " + Ref1);
if (Ref1.equals("Ref. de l'article : " + REF_1)) {
System.out.println("Reference 1 is correct");
} else {
System.out.println("Reference 1 is incorrect");
}
}
}
I am using extent report in TestCase.java(Please check above code) to report my scenarios, but the problem is It shows all test case as PASS and if any failure occurs it doesn't report(it terminates).
Reason being i have not used assertions anywhere, BUT HOW CAN I APPLY SUCH ASSERTIONS IN THIS FRAMEWORK
TO SUMMARIZE:
1- I need to add price validation check in report
2- i tried of using this line in TestCase.java "assertEquals("Verify REFERENCE 1", win.get(i).get(8), Lapeyre_frMainPage.GetREFERENCE());" but i cant use assertion in TestCase.java(it wont allow me).
3- Please show me alternative way to report PASS and FAIL for such frameworks, where in extent report i can able to show price mismatch between excel and UI.
You can only expect assertEquals() to work if your TestCase class extends junit test, or if you implement the method yourself in your code.
In any case, you seem to be trying to use ExtentReports. I am not experienced with that library, but according to the javadoc for ExtentTest, it appears that you are expected to call .pass() or .fail() yourself based on the outcome of your test.
In your TestCase, I believe you want to try to maintain a boolean to track if the test has passed or not.
The first step would be to modify VerifyREFERENCE() to return a boolean indicating if it passed or failed, instead of being void.
public boolean VerifyREFERENCE(String REF_1) throws Exception {
System.out.println("Verifying reference article");
if (REF_1.equals("SKIP")) {
System.out.println("SKIPPED");
} else {
WebElement referenceOne = tool.searchUsingXPath("//tbody//tr[1]//td//div[2]");
String Ref1 = referenceOne.getText().trim();
System.out.println("ref 1 is " + Ref1);
if (Ref1.equals("Ref. de l'article : " + REF_1)) {
System.out.println("Reference 1 is correct");
return true;
} else {
System.out.println("Reference 1 is incorrect");
return false;
}
}
}
Then, in your TestCase, initialise a boolean to true just before the loop. Inside the loop, perform a logical AND (&&) with the return value of each VerifyREFERENCE() call. Finally, after the loop finishes, test the value of the boolean, and pass or fail the ExtentTest as appropriate:
ExtentTest test1 = extent.createTest("Creamix test");
boolean passed = true;
for (String i : keys) {
System.out.println("########### Test = " + win.get(i).get(0) + " ###########");
Lapeyre_frMainPage.EnterTaille(win.get(i).get(1));
....
Lapeyre_frMainPage.SelectCHOISISSEZ(win.get(i).get(7));
passed = passed && Lapeyre_frMainPage.VerifyREFERENCE(win.get(i).get(8));(FROM HERE Validation Starts)
passed = passed && Lapeyre_frMainPage.VerifyQUANTITY(win.get(i).get(9));
...
passed = passed && Lapeyre_frMainPage.VerifyECO_PARTPrice(win.get(i).get(23));
Lapeyre_frMainPage.ClickCREAMIXReinit();(Reset button to test next scenario)
if(passed) {
test1.pass("Scenario " + win.get(i).get(0) + " is passed");
} else {
test1.fail("Scenario " + win.get(i).get(0) + " is failed");
}
System.out.println("########### Test End ##############");
extent.flush();----------(Extent report over)
}
I have changed all my multi-thread actions in my application to Akka a few weeks ago.
However, since it seems that I am starting to run out of Heap space (after a week or so).
By basically looking at all actors with
ActorSelection selection = getContext().actorSelection("/*");
the number of actors seems to increase all the time. After an hour of running I have more then 2200. They are called like:
akka://application/user/$Aic
akka://application/user/$Alb
akka://application/user/$Alc
akka://application/user/$Am
akka://application/user/$Amb
I also noticed that when opening websockets (and closing them) there are these:
akka://application/system/Materializers/StreamSupervisor-2/flow-21-0-unnamed
akka://application/system/Materializers/StreamSupervisor-2/flow-2-0-unnamed
akka://application/system/Materializers/StreamSupervisor-2/flow-27-0-unnamed
akka://application/system/Materializers/StreamSupervisor-2/flow-23-0-unnamed
Is there something specific that I need to do to close them and let them be cleaned?
I am not sure the memory issue is related, but the fact that there seem so many after an hour on the production server it could be.
[EDIT: added the code to analyse/count the actors]
public class RetrieveActors extends AbstractActor {
private String identifyId;
private List<String> list;
public RetrieveActors(String identifyId) {
Logger.debug("Actor retriever identity: " + identifyId);
this.identifyId = identifyId;
}
#Override
public Receive createReceive() {
Logger.info("RetrieveActors");
return receiveBuilder()
.match(String.class, request -> {
//Logger.info("Message: " + request + " " + new Date());
if(request.equalsIgnoreCase("run")) {
list = new ArrayList<>();
ActorSelection selection = getContext().actorSelection("/*");
selection.tell(new Identify(identifyId), getSelf());
//ask(selection, new Identify(identifyId), 1000).thenApply(response -> (Object) response).toCompletableFuture().get();
} else if(request.equalsIgnoreCase("result")) {
//Logger.debug("Run list: " + list + " " + new Date());
sender().tell(list, self());
} else {
sender().tell("Wrong command: " + request, self());
}
}).match(ActorIdentity.class, identity -> {
if (identity.correlationId().equals(identifyId)) {
ActorRef ref = identity.getActorRef().orElse(null);
if (ref != null) { // to avoid NullPointerExceptions
// Log or store the identity of the actor who replied
//Logger.info("The actor " + ref.path().toString() + " exists and has replied!");
list.add(ref.path().toString());
// We want to discover all children of the received actor (recursive traversal)
ActorSelection selection = getContext().actorSelection(ref.path().toString() + "/*");
selection.tell(new Identify(identifyId), getSelf());
}
}
sender().tell(list.toString(), self());
}).build();
}
}
I'm making a simple Player/Session system but I just found a logic error even that it seems to me that everything is in order.
Let me describe my idea, I'm still learning how OOP works, that's why I'm practicing in this project :
First of all I created two classes :
Class Players
Class Session
In the Session's class I have a method named joinSession(Session s);
This method will make the player's object join the session like so :
Session s1 = new Session();
Player p1 = new Player(name : "Jack");
p1.joinSession(s1);
The problem is that in the Session attributes I have a :
public Player firstPlayerToJoin;
public Player lastPlayerToJoin;
Whenever I make a player join a session everything seems to be fine, Jack is firstPlayerToJoin and lastPlayerToJoin. But the real probleem is when another player decides to join for example :
Player p2 = new Player("Rose");
p2.joinSession(s1);
Rose will once again be firstPlayerToJoin and lastPlayerToJoin instead of only being the lastPlayerToJoin.
Here's my code :
First Player class
private static int id;
private Session session;
boolean isOnSession = false;
public static String name;
public static void say(String message){
System.out.println(name + " says " + message);
}
// Player join session
public void joinSession(Session s){
this.session = s;
System.out.println(name + " joined the session : " + this.session.sessionName );
System.out.println("Players ONLINE = " + s.playersOnline);
if( s.playersOnline == 0){
s.firstPlayerToJoin = this;
s.lastPlayerToJoin = this;
} else {
s.lastPlayerToJoin = this;}
s.playersOnline++;
}
public void quitSession(){
this.session = null;
isOnSession = false;
System.out.println(name + " left his session.");
}
Player(String name){
id = id++;
this.name = name;
}
public static void showPlayerInfo(Player n){
System.out.println("========== Player INFO ==========");
System.out.println("ID : " + id + "\nName : " + name );
}
}
Here's Session class :
public class Session {
int id = 0;
int maxConnected = 10;
public int playersOnline = 0;
String[] playersConnected = new String[maxConnected];
public String sessionName;
public Player firstPlayerToJoin;
public Player lastPlayerToJoin;
Session(){
this.id=id++;
this.sessionName = "SESSION"+id;
}
public void sessionInfo(){
System.out.println("======== Session INFO ========");
System.out.println("Session name : " + sessionName);
System.out.println("Players online : " + playersOnline);
System.out.println("First player to join : " + firstPlayerToJoin.name);
System.out.println("Last player to join : " + lastPlayerToJoin.name);
System.out.println("==============================");
}
int getPlayersOnline(){
return this.playersOnline;
}
}
And finally the main class and method :
public class Main {
public static void main(String[] args) {
Player p1 = new Player("Omar");
Session s1 = new Session();
p1.joinSession(s1);
s1.sessionInfo();
Player p2 = new Player("Rick");
p2.joinSession(s1);
s1.sessionInfo();
}
}
If there's any question or confusion about the idea, let me know.
Actual output :
Omar joined the session : SESSION0
Players ONLINE = 0
======== Session INFO ========
Session name : SESSION0
Players online : 1
First player to join : Omar
Last player to join : Omar
==============================
Rick joined the session : SESSION0
Players ONLINE = 1
======== Session INFO ========
Session name : SESSION0
Players online : 2
First player to join : Rick
Last player to join : Rick
==============================
In the line just before the last one we can see : First player to join : Rick
Player's object p1 overrides the attribute even if there's a condition that's not true.
I am going to elaborate on RealSkeptic's comment (which I did not figure out until he said it).
You have your name field as static. Currently, if you were to write (p1 == p2) you would get false, because they are indeed different objects. By making this a static variable, you are setting it for your entire class (Static variables are called class variables). What you intended to do is localize your variable so that your individual players would have their own names.
Therefore:
public static String name;
should be:
public String name;
Your IDE is probably telling you that you are accessing name in an incorrect way right now. When accessing static variables or methods, you access them through the class themselves rather than objects of that class.
e.g.
Player.NAME
rather than
Player p1 = new Player("tom");
p1.NAME;
because, as mentioned, they are for the class themselves rather than local object instantiations of said class. Here is some further reading if you would like:
My test part is the following:
#Test
//testing user report method of UserAdmin - number of users less than 10
public void testuserReport_SizeLessThan10() throws Exception
{
new Expectations() {{
dBConnection.getUsers();
times=1;
result= Arrays.asList("Abc","123");
}};
System.out.println("in less than 10");
userAdmin.runUserReport();
}
The method under test belonging to a class named userAdmin is the following:
public void runUserReport() {
try {
List<User> users = dbConn.getUsers();
System.out.println(users.size());
if (users.isEmpty()) { // empty database
System.out.println("No users in database...");
} else if (users.size() <= 10) { // detailed reporting
System.out.println("Listing all usernames:");
for (User user : users) {
System.out.println(user.getUsername());
}
} else { // summary reporting
System.out.println("Total number of users: " + users.size());
System.out.println(users.get(0).getUsername());
System.out.println(users.get(1).getUsername());
System.out.println(users.get(2).getUsername());
System.out.println(users.get(3).getUsername());
System.out.println(users.get(4).getUsername());
System.out.println((users.size() - 5) + " more...");
}
} catch (SQLException sqle) {
System.out.println("DBConnection problem at runUserReport().");
}
}
My tests runs by giving the size of users as 2 but it does not print the usernames starting with "Listing all usernames:" as defined in the method. Am i defining the result wrongly in the expectations part of the test? Please help
I am not even sure how come System.out.println(users.size()); prints the size as 2 and not the test fails.
List<User> users = dbConn.getUsers(); says that users is a List of User type while result= Arrays.asList("Abc","123"); makes result as List of String, List<String>. You are assigning List<String> to List<User> and somehow it doesn't fail at run time.
You need to prepare a List of User type and assign to result instead of what you are doing currently.
Please, i have some problems with my web application.
I can't paste my code here ( too big and i have the difficulty to reproduce the error ) but, this is my issus.
I have a object that contains a collection. I use BlockquingQueue to share this objet betwen some thread. the second kind of thread is a servlet.
When i put my objet in the queue, the collection is not empty and i can display thier element.
But, when i take the same element, the collection size is not null, but it don't have elements.
NB: I don't have problems to get the objet in queue. My problems it which their attribute of type Collection. It show me a strange behavoir.
a big part of a code:
public class HttpCollectionConsumer extends JCasAnnotator_ImplBase{
private static BlockingQueue<Answer> queue = new LinkedBlockingQueue<>();
private static boolean hasNext = true;
public void initialize(UimaContext context) throws ResourceInitializationException{
super.initialize(context);
}
#Override
public void process(JCas jcas) throws AnalysisEngineProcessException {
// TODO Auto-generated method stub
edu.cmu.lti.oaqa.type.input.Question q = TypeUtil.getQuestion(jcas);
System.out.println("get Text " + q.getText());
Question question = new Question(q.getId() , q.getText());
Focus focus = TypeUtil.getFocus(jcas);
Collection<LexicalAnswerType> types = TypeUtil.getLexicalAnswerTypes(jcas);
Answer a = new Answer();
a.setQuestion(question);
a.setFocus(focus);
a.setTypes(types);
try {
System.out.println("identifiant : ( " + a + " ) types " + a.getTypes().iterator().next());
System.out.println("the answer type is not empty : " + a.getTypes().iterator().hasNext());
synchronized(this){
queue.put(a);
Thread.sleep(1000);
}
System.out.println("putting finished " );
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static synchronized void put(Answer question) throws InterruptedException{
System.out.println("new answer : " + question);
queue.offer(question);
}
public synchronized static Answer take() throws InterruptedException{
Answer a = queue.take();
Thread.sleep(2000);
System.out.println(" someone takess ( " + a + " ) , remaining: " + queue.size());
System.out.println("the answer type is not empty : " + a.getTypes().iterator().hasNext());
return a;
}
public synchronized static BlockingQueue<Answer> getQueue(){
return queue;
}
public synchronized static void stop(){
hasNext = false;
}
}
Someone can know why ?
You can only get a item from a Queue once, First Object In First Out. If you want to access a object more than once or directly you should use a List and transform that into a Collection.
Also, if you share your object between Threads only one of the Threads will be able to access the mentioned object, since after being processed by one it won't be in the Queue anymore.