I want to test this method:
if (user != null) {
userDAO.delete(user);
sessionService.logout(user.getEmail());
}
}
this is my Test:
public void deleteTest(){
doNothing().when(userDAO).delete(user);
doNothing().when(sessionService).logout("");
sessionInvalidationDecorator.delete(user);
verify(userDAO, times(1)).delete(user);
verify(sessionService, times(1)).logout("");
}
but I get:
Wanted but not invoked:
sessionService.logout("");
-> at de.unibremen.swp.controller.SessionInvalidationDecoratorTest.deleteTest(SessionInvalidationDecoratorTest.java:69)
Actually, there were zero interactions with this mock.
I don't know what I do wrong
Thanks in advance.
The problem was that you are indicating the value that logout must have, in this case when it is mocked, and referring to user.getEmail() is waiting for you to return a " " and instead you are returning a string from getEmail
I guess that your user.getMail does not return the empty string that you verify.
You have to make sure that user.getMail returns a string that is equal to the one you verify.
Here is a complete example that works.
public class SessionInvalidationDecoratorTest {
private UserDAO userDAOMock;
private SessionService sessionServiceMock;
private SessionInvalidationDecorator sessionInvalidationDecorator;
#Before
public void setup() {
userDAOMock = Mockito.mock(UserDAO.class);
sessionServiceMock = Mockito.mock(SessionService.class);
sessionInvalidationDecorator = new SessionInvalidationDecorator(userDAOMock, sessionServiceMock);
}
#Test
public void deleteTest() {
User user = new User();
user.setEmail("mail#some-domain.com");
sessionInvalidationDecorator.delete(user);
Mockito.verify(userDAOMock, Mockito.times(1)).delete(user);
Mockito.verify(sessionServiceMock, Mockito.times(1)).logout("mail#some-domain.com");
}
}
public class SessionInvalidationDecorator {
private UserDAO userDAO;
private SessionService sessionService;
public SessionInvalidationDecorator(UserDAO userDAO, SessionService sessionService) {
this.userDAO = userDAO;
this.sessionService = sessionService;
}
public void delete(User user) {
if (user != null) {
userDAO.delete(user);
sessionService.logout(user.getEmail());
}
}
}
public interface SessionService {
void logout(String email);
}
public interface UserDAO {
void delete(User user);
}
public class User {
private String email;
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
}
Related
For teaching purposes I want to provide an example with dirty reads. Using the READ_UNCOMMITED isolation level. However I am not able to get this example working. I tried many different things but it still does not work. So I hope you are able to help me.
Scenario:
Start transaction “main”
Insert person in new transaction (“main” transaction is suspended)
Update name of person in main transaction
Flush update
Read person in new transaction (isolation level is READ_UNCOMMITTED)
Should read data of updated person --> This does not work!
Revert main transaction by throwing RuntimeException
Assert that that original name of person is in database --> This works
See code below for more info.
I also tested against a Postgres database but that made no difference. Also tried to do everything with JDBC templates instead of an ORM mapper but that made no difference either.
Thanks in advance.
Best regards,
Marinus
IsoliationLevelTest (src/test/java/test)
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {SpringBootTestApplication.class})
public class IsoliationLevelTest {
#Autowired
private TestService testService;
#Autowired
private UtilService serviceUtil;
#After
public void tearDown() {
serviceUtil.deleteTestPersons();
}
#Test
public void testIsolationLevel() {
try {
testService.testIsolationLevel("Piet", "PietUpdated");
} catch (TestService.TestException e) {
List<PersonJPAEntity> persons = serviceUtil.retrieveTestPersons();
assertEquals(1, persons.size());
assertEquals("Piet", persons.get(0).getName());
assertEquals("PietUpdated", e.getPersonReadInNewTransaction().getName());
}
}
}
SpringBootTestApplication (src/main/java/test)
#SpringBootApplication
#EnableAspectJAutoProxy(exposeProxy = true)
public class SpringBootTestApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootTestApplication.class, args);
}
}
TestService
#Service
#Transactional(isolation = Isolation.READ_UNCOMMITTED)
public class TestService {
Logger logger = LoggerFactory.getLogger(TestService.class);
#Autowired
private PersonRepository personRepository;
#Transactional(propagation = REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED)
public void testIsolationLevel(String initialName, String newName) {
//Requires_new propagation so transaction is committed after person is save
TestService self = (TestService) AopContext.currentProxy();
self.insertPerson(new PersonJPAEntity(1, initialName));
//Required propagation so this update runs in current transaction (which is not committed yet)
self.updatePerson(newName);
PersonJPAEntity personReadInNewTransaction = self.findPersonInNewTransaction();
logger.info("Throw exception and thereby rollback transaction");
throw new TestException("Rollback transaction", personReadInNewTransaction);
}
#Transactional(propagation = REQUIRES_NEW)
public void insertPerson(PersonJPAEntity person) {
personRepository.save(person);
logger.info("Person inserted {}", person);
}
#Transactional(propagation = REQUIRED)
public void updatePerson(String newName) {
Optional<PersonJPAEntity> personToUpdate = personRepository.findById(1);
personToUpdate.get().setName(newName);
logger.info("Person updated {}", personToUpdate);
personRepository.flush();
logger.info("Repository flushed");
}
#Transactional(propagation = REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED)
public PersonJPAEntity findPersonInNewTransaction() {
Optional<PersonJPAEntity> person = personRepository.findById(1);
logger.info("Person found in new transaction {}", person);
return person.get();
}
public class TestException extends RuntimeException {
private final PersonJPAEntity personReadInNewTransaction;
public TestException(String message, PersonJPAEntity personReadInNewTransaction) {
super(message);
this.personReadInNewTransaction = personReadInNewTransaction;
}
public PersonJPAEntity getPersonReadInNewTransaction() {
return personReadInNewTransaction;
}
}
}
PersonRepository
public interface PersonRepository extends JpaRepository<PersonJPAEntity, Integer> {
List<PersonJPAEntity> findByOrderByIdAsc();
}
UtilService
#Service
public class UtilService {
#Autowired
PersonRepository personRepository;
#Transactional(propagation = REQUIRES_NEW)
public List<PersonJPAEntity> retrieveTestPersons() {
return personRepository.findByOrderByIdAsc();
}
#Transactional(propagation = REQUIRES_NEW)
public void deleteTestPersons() {
personRepository.deleteAll();
}
}
PersonJPAEntity (src/main/java/test)
#Entity(name = "person")
public class PersonJPAEntity {
#Id
private int id;
private String name;
private PersonJPAEntity() {
}
PersonJPAEntity(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PersonJPAEntity)) return false;
PersonJPAEntity person = (PersonJPAEntity) o;
return id == person.id &&
Objects.equals(name, person.name);
}
#Override
public int hashCode() {
return Objects.hash(id, name);
}
#Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
application.properties (src/main/resources)
# spring.jpa.show-sql=true
logging.level.org.springframework.transaction=TRACE
How to finish validation with sending all form data in Vaadin 8? Unfortunetly I dont understand binder concept :( I wrote a field validation but what now? It works. My user see when I demand that he fill out a field but is there any easy way to validate my all form? How can I "tell" to my save button that my form is valid?
In my editor Im defining a validator
#SpringComponent
#PrototypeScope
public class VaadinStringEditor extends TextField implements HasValueComponent<String> {
private Binder<String> binder;
BinderValidationStatus<String> status;
#PostConstruct
public void init() {
setWidth("100%");
binder = new Binder<>();
}
#Override
public void initDefaults() {
setValue("");
status = binder.validate();
}
#Override
public void setConfiguration(EditorConfiguration editorConfiguration) {
Validator<String> validator = ((TextFieldConfiguration) editorConfiguration).getValidator();
if (validator != null) {
binder.forField(this).withValidator(validator).asRequired("Mandatory").bind(s -> getValue(),
(b, v) -> setValue(v));
}
public BinderValidationStatus<String> getStatus() {
return status;
}
public void setStatus(BinderValidationStatus<String> status) {
this.status = status;
}
public boolean validate() {
BinderValidationStatus<String> status = binder.validate();
return status.isOk();
}
}
}
I have also an TextEditorConfiguration added:
public class TextFieldConfiguration implements EditorConfiguration {
private Validator<String> validator;
private int validated;
public TextFieldConfiguration(Validator<String> validator) {
this.validator = validator;
}
public TextFieldConfiguration() {
this.validator = null;
}
public Validator<String> getValidator() {
return validator;
}
public int getValidated() {
return validated;
}
public void setValidated(int validated) {
this.validated = validated;
}
}
In my case there are plenty of editors like DateEditor and so on. UI Valtidation works well. Since one month I can not find a way how to connect it to submit button to prevent send a form.
In the form class I have defined all questions
for example:
question = new AseQuestion(AseQuestionId.DATE_OF_NOTIFICATION, EditorType.DATE_EDITOR);
question.setDescription(
"When it happend?");
question.setEditorConfiguration(new DateFieldConfiguration(dateRequiredValidator(), dateNotAllowedValidator()));
return question;
question = new AseQuestion(AseQuestionId.QUESTION2, EditorType.STRING_EDITOR);
question.setDescription("
"Write something");
private Validator<String> textRequiredValidator() {
return Validator.from(v -> v != null && StringUtils.trimAllWhitespace((String) v).length() != 0,
"It cannot be empty!!!");
And the class where I have a submit button
public class QuestionWindow extends Window {
#Autowired
private transient VaadinStringEditor editor;
private Button createSaveButton() {
Button saveButton = new Button(i18n.getWithDefault("newAseQuestions.save", "Übernehmen"));
saveButton.addClickListener(e -> {
if (editor.getBinder.validate()) {
Notification.show("This is the caption OK", "This is the description",
Notification.Type.HUMANIZED_MESSAGE);
} else {
Notification.show("This is the caption", "This is the description",
Notification.Type.HUMANIZED_MESSAGE);
System.out.println("kurwa");
}
saveAse();
});
return saveButton;
}
OK lets assume we haven this POJO:
public class Person {
private String firstname;
private String lastname;
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
}
And we want to edit it.
So we build the following form:
public class Form {
private TextField firstname;
private TextField lastname;
private Binder<Person> binder = new Binder<>();
void bindFields() {
binder.forField(firstname).withValidator(textRequiredValidator())
.asRequired("Mandatory").bind(Person::getFirstname, Person::setFirstname);
binder.forField(lastname).withValidator(textRequiredValidator())
.asRequired("Mandatory").bind(Person::getLastname, Person::setLastname);
}
public void setDatasource(Person person) {
binder.setBean(person);
}
private Validator<String> textRequiredValidator() {
return Validator.from(v -> v != null && StringUtils.trimAllWhitespace((String) v).length() != 0,
"It cannot be empty!!!");
}
public boolean validate() {
BinderValidationStatus<Person> status = binder.validate();
return status.isOk();
}
}
In order to use this form we need to call bindFields first (e.g. constructor, init).
Than a controller or so calls setDatasource with the person we want to edit.
After this the user can fill or edit the form and when the user finishes the status of the form can be retrieved via validate.
If you need the errors from the fields you get them from the BinderValidationStatus.
For more information look at https://vaadin.com/docs/v8/framework/datamodel/datamodel-forms.html
I've created this User class:
#Entity
public class User extends Model {
#Id
#Constraints.Email
public String email;
#Constraints.MinLength(3)
#Constraints.MaxLength(255)
public String firstName;
#Constraints.MinLength(3)
#Constraints.MaxLength(255)
public String lastName;
#Constraints.MinLength(3)
#Constraints.MaxLength(255)
public String username;
#Constraints.MinLength(16)
#Constraints.MaxLength(255)
public String password;
public static Finder<String, User> finder = new Finder<>(User.class);
public static User create(User user){
user.password = BCrypt.hashpw(user.password, BCrypt.gensalt(12));
user.save();
return user;
}
...
}
And I noticed that I can save an empty User. Which means, with no email, nothing, this User will be persisted on my database.
#Test
public void createEmptyUser(){
User user = new User();
user.email="";
user.save();
assertTrue(user.email.isEmpty());
assertNotNull(User.finder.byId(user.email));
assertEquals(true, User.findByEmail(user.email).isPresent());
}
Why is my test passing ?
As I can see here https://github.com/playframework/playframework/blob/master/framework/src/play-java-forms/src/main/java/play/data/validation/Constraints.java the isValid method of the EmailValidator class returns true if its agrument is an empty string:
public static class EmailValidator extends Validator<String> implements ConstraintValidator<Email, String> {
public boolean isValid(String object) {
if(object == null || object.length() == 0) {
return true;
}
return regex.matcher(object).matches();
}
}
Consider adding #Constraints.Requiredand #Formats.NonEmpty to this validation. Also, you can see that the MinLength and MaxLength validators behave in the same way.
I have an issue in programming an EJB application. I search a solution but I still have the same problem in intelliJ with Glassfish4 :
" Cannot resolve reference [Local ejb-ref name=EJB.AdminEJB,Local 3.x interface =Interface.AdminInterface,ejb-link=null,lookup=,mappedName=,jndi-name=,refType=Session] because there are [2] ejbs in the application with interface Interface.AdminInterface."
And excuse-me for my english, I'm french.
AdminInterface in a package Interface
#Local
public interface AdminInterface {
public void creerParieur(Parieur parieur);
public void supprimerParieur (String login);
public void creerBookmaker(Bookmaker bookmaker);
public void supprimerBookmaker (String login);
public void modifParieur (Parieur parieur);
public void modifBookmaker (Bookmaker bookmaker);
public void ajouterCote(Cote cote);
public void ajouterMatch (Match match);
public List<Cote> listeCote(String log);
public List<Match> listeMatch();
public List<Parieur> listeParieur();
public List<Bookmaker> listeBookmaker();
public Parieur rechercheParieur(String id);
public Bookmaker rechercheBookmaker (String id);
public void setLogin(String login);
public String getLogin();
}
AdminEJB in a package EJB
#Stateless
public class AdminEJB implements AdminInterface{
String login;
String mdp;
#PersistenceContext(unitName = "NewPersistenceUnit")
EntityManager em;
public AdminEJB(){}
public String getLogin(){
return login;
}
public void setLogin(String login){
this.login=login;
}
public String getMdp(){
return mdp;
}
public void setMdp(String mdp){
this.mdp=mdp;
}
public void creerParieur(Parieur parieur){
em.persist(parieur);
}
public void supprimerParieur(String login){
Parieur parieur=new Parieur ();
Query req=em.createQuery("select OBJECT(P) from Parieur P where P.login=:login");
req.setParameter("login", login);
parieur=(Parieur)req.getSingleResult();
em.remove(parieur);
}
public void modifParieur(Parieur parieur){
em.merge(parieur);
}
public List<Parieur> listeParieur(){
Query req=em.createQuery("select OBJECT(P) from Parieur P");
return req.getResultList();
}
public void creerBookmaker(Bookmaker bookmaker){
em.persist(bookmaker);
}
public void supprimerBookmaker(String login){
Bookmaker bookmaker;
Query req=em.createQuery("select OBJECT(B) from Bookmaker B where B.pseudo=:login");
req.setParameter("login", login);
bookmaker=(Bookmaker)req.getSingleResult();
em.remove(bookmaker);
}
public void modifBookmaker(Bookmaker bookmaker){
em.merge(bookmaker);
}
public List<Bookmaker> listeBookmaker(){
Query req=em.createQuery("select OBJECT(B) from Bookmaker B");
return req.getResultList();
}
public List<Match> listeMatch(){
Query req=em.createQuery("select OBJECT(M) from Match M");
return req.getResultList();
}
public Bookmaker rechercheBookmaker(String id){
return em.find(Bookmaker.class,id);
}
public Parieur rechercheParieur(String id){
return em.find(Parieur.class,id);
}
public void ajouterCote (Cote cote){
em.persist(cote);
}
public void ajouterMatch (Match match){
em.persist(match);
}
public List<Cote> listeCote(String log){
Bookmaker bookmaker = new Bookmaker();
bookmaker = this.rechercheBookmaker(log);
Query req = em.createQuery("select OBJECT(C) from Cote C where C.bookmaker=:bookmaker");
req.setParameter("bookmaker", bookmaker);
return req.getResultList();
}
}
ControlerBean in a package ManagedBean
#ManagedBean
#RequestScoped
public class ControlerBean implements Serializable{
Bookmaker bookmaker;
Pari pari;
Parieur parieur;
Match match;
Cote cote;
String nomObjetP;
String nomEnP;
String pseudoUser;
String pwdUser;
#EJB
private AdminInterface admin;
public ControlerBean(){
bookmaker = new Bookmaker();
parieur = new Parieur();
cote = new Cote();
match= new Match();
pari= new Pari();
}
public String getNomObjetP() {
return nomObjetP;
}
public void setNomObjetP(String nomObjetP) {
this.nomObjetP = nomObjetP;
}
public String getNomEnP() {
return nomEnP;
}
public void setNomEnP(String nomEnP) {
this.nomEnP = nomEnP;
}
public Pari getPari() {
return pari;
}
public void setPari(Pari pari){
this.pari=pari;
}
public Bookmaker getBookmaker() {
return bookmaker;
}
public void setBookmaker(Bookmaker bookmaker) {
this.bookmaker = bookmaker;
}
public Parieur getParieur() {
return parieur;
}
public void setParieur(Parieur parieur) {
this.parieur = parieur;
}
public Cote getCote() {
return cote;
}
public void setCote(Cote cote) {
this.cote = cote;
}
public Match getMatch(){
return match;
}
public void setMatch(Match match){
this.match=match;
}
public AdminInterface getAdmin() {
return admin;
}
public void setAdmin(AdminInterface admin) {
this.admin = admin;
}
public String getPseudoUser() { return pseudoUser; }
public void setPseudoUser(String pseudoUser) {
this.pseudoUser = pseudoUser;
}
public String getPwdUser() {
return pwdUser;
}
public void setPwdUser(String pwdUser) {
this.pwdUser = pwdUser;
}
public String addParieur(){
parieur.setArgent(1000);
admin.creerParieur(parieur);
return "OK";
}
public String modifParieur(){
admin.modifParieur(parieur);
return "OK";
}
public String supprParieur(){
admin.supprimerParieur(parieur.getLogin());
return "OK";
}
public String addBookmaker(){
admin.creerBookmaker(bookmaker);
return "OK";
}
public String modifBookmaker(){
admin.modifBookmaker(bookmaker);
return "OK";
}
public String supprBookmaker(){
admin.supprimerBookmaker(bookmaker.getPseudo());
return "OK";
}
public List<Bookmaker> listeBookmaker(){
return admin.listeBookmaker();
}
public List<Parieur> listeParieur(){
return admin.listeParieur();
}
public List<Match> listeMatch(){ return admin.listeMatch(); }
public String addCote(){
pseudoUser = admin.getLogin();
cote.setBookmaker(admin.rechercheBookmaker(pseudoUser));
admin.ajouterCote(cote);
return "OK";
}
public String addMatch(){
admin.ajouterMatch(getMatch());
return "OK";
}
}
Thank's very much for any help
When you have two EJBs implementing the same interface they need to be differentiated so that the container knows which one to inject.
Add the name parameter in the #Stateless annotation to all beans implementing the same interface. In the #EJB annotation, use the beanName parameter to inject the appropriate session bean implementation.
#Stateless(name="AdminEJB1")
public class AdminEJB implements AdminInterface { .... }
#EJB(beanName = "AdminEJB1")
private AdminInterface myAdminEjb;
You can also skip the name parameter in the #Stateless annotation and then use the name of the implementing class as the beanName parameter in the #EJB annotation.
#Stateless
public class AdminEJB implements AdminInterface { .... }
#EJB(beanName = "AdminEJB")
private AdminInterface myAdminEjb;
I had same error, but I didn't work with one interface for different EJBs (generated local Session Beans from entity classes). So I am putting this answer if somebody had same problem as me, as I didn't found one here. My framework generated "ejb-local-ref" tag in pom.xml on its own. After deleting it, all works perfectly.
Another cause for this problem, although uncommon, may be the delay in communicating with the JMX port. To get around this it is possible to put the key -Dhk2.parser.timeout = 300
I have an app (Spring MVC + Hibernate) and AppFuse Framework too.
I have two entities: User and Robot with a Many-To-One relationship.
I need to add a drop down list to for owner (User) to the Robot form (robotForm.jsp).
The Robot entity has a User. I read that I must create a custom Editor for User. (UserCustomEditor extends PropertyEditorSupport) and override referenceData in the RobotFormController add in the initBinder too.
RobotFormController
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat(getText("date.format"));
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, null,
new CustomDateEditor(dateFormat, true));
binder.registerCustomEditor(Long.class, null,
new CustomNumberEditor(Long.class, null, true));
binder.registerCustomEditor(User.class, new UserEditor(userManager));
}
// ...
protected Map referenceData(HtppServletRequest request) throws Exception {
Map ownersMap = new HashMap();
ownersMap.put("owners", userManager.getUsers();
return ownersMap;
}
userManager.getUsers(); return a List of Users.
UserEditor (maybe here is my error).
public class UserEditor extends PropertyEditorSupport {
private final UserManager userManager;
protected final transient Log log = LogFactory.getLog(getClass());
public UserEditor(UserManager userManager) throws IllegalArgumentException {
this.userManager = userManager;
}
#Override
public void setAsText(String text) throws IllegalArgumentException {
if (text != null && text.length() > 0) {
try {
User user = userManager.getUser(new String (text));
super.setValue(user);
} catch (NumberFormatException ex) {
throw new IllegalArgumentException();
}
} else {
super.setValue(null);
}
}
#Override
public String getAsText() {
User user = (User) super.getValue();
return (user != null ? (user.getId()+"").toString(): "");
}
}
robotForm.jsp
<form:select path="owner" itemValue="id" itemLabel="name" items="${owners}"
</form:select>
I get a NullPointerException in the
ownersMap.put("owners", userManager.getUsers(); line of the referenceData method.
Edit:
UserManagerImpl
#Service(value = "userManager")
public class UserManagerImpl implements UserManager {
#Autowired
UserDao dao;
public void setUserDao(UserDao dao) {
this.dao = dao;
}
public List getUsers() {
return dao.getUsers();
}
public User getUser(String userId) {
return dao.getUser(Long.valueOf(userId));
}
public void saveUser(User user) {
dao.saveUser(user);
}
public void removeUser(String userId) {
dao.removeUser(Long.valueOf(userId));
}
}
Robot.java
public class Robot extends BaseObject {
private static final long serialVersionUID = -1932852212232780150L;
private Long id;
private String name;
private Date birthday;
private User owner;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
}
The only thing I am seeing why you are having a null in there is that 'userManager' has not been instantiated.
You can check if it has been through (userManager == null).
Your code looks good to me, not looking into the logic. I think your configuration of Spring's IoC is the problem here.
Can you post your *.xml files.
This would help out solve your problems.
Cheers!