• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[Code-review] Prosta apka CRUD z systemem logowania do zarządzania todolistami - Java, Spring, Hibernate

Object Storage Arubacloud
+1 głos
1,117 wizyt
pytanie zadane 23 września 2017 w Nasze projekty przez Codeboy Stary wyjadacz (12,120 p.)
edycja 23 września 2017 przez Codeboy

W celu nauki Javy i jej technologii pisze sobie taką oto apkę webową:
github.com/C0deboy/todo-list-app

Używam Spring MVC, Spring Security, Hibernate, JSP, MySQL, Tomcat i Maven. Zacząłem raczkować też z JUnit i nauką pisania testów.


Ma już podstawowe funkcjonalności takie jak zarządzanie todolistami, kontem i system logowania. 

Chciałbym zorientować się jak mi to idzie, a więc poprosić o code-review - rady, wskazówki, wytknięcie błędów, zasugerowanie dobrych praktyk i czegokolwiek innego co mi pomoże w pisaniu lepszego kodu.

Z góry dzięki za poświęcony czas ;)

1 odpowiedź

0 głosów
odpowiedź 24 września 2017 przez ShiroUmizake Nałogowiec (46,300 p.)

1. Jak masz interfejsy to je oznaczaj jakoś np: IEmailService lub MessageAble. Ok, dobra dalej zobaczyłem, że masz impl.

private final String from = "email@gmail.com";

Jeżeli masz pole z klasyfikatorem dostępu final, oznacza się dla ułatwienia za pomocą dużych liter.

private final TodoListDAO todoListDAO;

Dlaczego final? ;d Plus, że znasz DAO no i pojęcie trasnakcji. Na przyszłośc radzę się zainteresować entityMenager znacznie łatwiej się tworzy się zapytania dla connectora w JAVA. Tymbardziej, że przy zawansowanych pytaniach SQL to można normalnie włosy stracić.

Ogólnie ładnie i schludnie. Robiłeś sam czy za pomocą poradnika?

Ale testy za to mi się nie podobają. 


 public void addUser() throws Exception {
        currentSession = userDAO.getSessionFactory().getCurrentSession();

        User testUser = new User("Test", "Test123$", "test@test.com");

        userDAO.addUser(testUser);

        user = userDAO.getUserByName(testUser.getUsername());

        assertNotNull(user);
    }

Przede wszystkim ta nazwa nic mi nie mówi co jest testowane. Podejść jest parę do typu nazewnictwa. jednym z nich jest takie: user_should_be_not_null.

Po drugie, możesz sobie utworzyć 'setup' bo jakiś miał powiedzmy 3000 testów a w każdym z nich występuje User to te testy trochę dłużej trwały.

 Po trzecie, nas za bardzo nie interesuje co ten user sobie tam zawiera, my chcemy sprawdzić czy nasza aplikacja zachowa się zgodnie z założeniami. Czyli możemy zmockować obiekt userDAO. gdy samo pisanie testów jednostkowych bez mockowania jest dość proste to już badanie zachowania za pomocą mock to już trochę trzeba posiedzieć. 

Tymbardziej warto się ich nauczyć dla przykładu gdy będziesz musiał napisać testy dla sharePoolSQL powiedzmy dla Oracle, no tam nie utworzysz 15 obiektów wstecz, bo możesz nawet nie wiedzieć jakie to mogą być wartości. Wiem to już jest ekstremalne. Ale taki bardziej przyziemny przypadek to np: badanie działania sesji, np czy użytkownik faktycznie zostanie gdzieś tam przekierowany.

Testuj wszystko nawet najprotsze domeny obiektowe, nie kosztuje cię to za wiele, a będziesz miał pewność , że nagle coś tam na dole się popsuło. Plus załapiesz punkt, że stosujesz podejście TDD.

ublic void crudTask() throws Exception {
        TodoList newTodoList = new TodoList("Test", user.getId());

        System.out.println(newTodoList);
        todoListDAO.addTodoList(newTodoList);

        TodoList todoList = todoListDAO.getTodolistsFor(user).get(0);

        Task task = new Task("Test", todoList);


        todoListDAO.addTask(task);

        currentSession.flush();
        currentSession.refresh(todoList);

        todoList = todoListDAO.getTodolistsFor(user).get(0);

        assertTrue("Should be added 1 task but is not", todoList.getTasks().size() == 1);

        Task taskToBeChanged = todoList.getTasks().get(0);
        String newTaskName = "Changed task name";

        todoListDAO.toggleDone((byte) 1, taskToBeChanged.getId());
        todoListDAO.changeTaskName(taskToBeChanged.getId(), newTaskName);

        currentSession.refresh(taskToBeChanged);

        todoList = todoListDAO.getTodolistsFor(user).get(0);

        Task retrivedTask = todoList.getTasks().get(0);

        assertEquals("Retrived task name should be changed", newTaskName, retrivedTask.getTask());
        assertEquals("Retrived task done state should be 1", 1, retrivedTask.getDone());

        todoListDAO.deleteTask(todoList.getTasks().get(0).getId());

        todoList = todoListDAO.getTodolistsFor(user).get(0);
        currentSession.refresh(todoList);

        assertTrue("Task should be deleted but is not",todoList.getTasks().size() == 0);
    }

I tu masz taki przypadek, zdecydowanie za długi ten test. Po pierwszy jest zły. Jeden test, bada jedną rzecz i wbij to sobie do głowy. Powiedzmy, że mam tych 10000 testów i ten jeden się nie wykona, i na który assert mam patrzeć? tam gdzie się równa , tam gdzie sprawdzam assercję. Nie wiem. Po drugie jest za bardzo zależna.   

 

WAŻNA RZECZ:

Jak już masz jakąś aplikację, warto by było napisać jak należy ją uruchomić! 

Przejdżmy jeszcze do JS, bo widzę, że tutaj coś też mamy. 

Ok, na początek fajna podpowiedż, jeżeli wywołujesz zdarzenie od rodzica , to te zdarzenie również jest dostępne dla dzieci. 

Przykład:

https://codepen.io/shiroUmizake/pen/jGVBYr

Dlaczego tak się dzieje, musisz sam zbadać. 

Przez co nie będziesz musiał tych brzydkich (aczkolwiek potrzebnych) foreach. Bo trochę brzydzą kod.

Póżniej ci dołoże kolejne komentarze. xd. Muszę uciekać xd.

1
komentarz 24 września 2017 przez Codeboy Stary wyjadacz (12,120 p.)

Dzięki za feedback. Z niecierpliwością czekam na ciąg dalszy ;)

Ogólnie ładnie i schludnie. Robiłeś sam czy za pomocą poradnika?

Apkę robię sam, główne źródła to dokumentacja lub Stack Overflow. Czasem jakiś przyład na blogu.

Dlaczego final? ;d Plus, że znasz DAO no i pojęcie trasnakcji. 

Hmm, InteliJ podczas wstrzykiwania zależności bezpośrednio do pól przez @Autowired zasugerował "dobrą praktykę", żeby robić to przez konstruktor. Gdy zastosowałem automatyczne wykonanie roboty przez InteliJ to dodał mi modyfikator final. Sam się zastanawiam czemu, musi być jakiś powód :D Może ty się domyślasz?

Na przyszłośc radzę się zainteresować entityMenager znacznie łatwiej się tworzy się zapytania dla connectora w JAVA. Tymbardziej, że przy zawansowanych pytaniach SQL to można normalnie włosy stracić.

Okey, mniej więcej rozumiem różnice między SessionFactory i EntityManager, widzę jakie mają zalety, jednak w tym projekcie nie ma nic przeciwko SessionFactory hmm? Czy zawsze powinno się preferować EntityManager?

Ale testy za to mi się nie podobają. 

No z testami dopiero raczkuję.

Przede wszystkim ta nazwa nic mi nie mówi co jest testowane. Podejść jest parę do typu nazewnictwa. jednym z nich jest takie: user_should_be_not_null.

Po drugie, możesz sobie utworzyć 'setup' bo jakiś miał powiedzmy 3000 testów a w każdym z nich występuje User to te testy trochę dłużej trwały.

Setup to znaczy co? Masz na myśli, ze przed każdym testem są tworzone potrzebne obiekty? Jeśli tak, to to co zakomentowałeś czyli addUser() jest "setupem". Jest oznaczone z @Before, więc wykonuje się przed każdym tekstem. Czy źle Cię zrozumiałem?

Czyli możemy zmockować obiekt userDAO. gdy samo pisanie testów jednostkowych bez mockowania jest dość proste to już badanie zachowania za pomocą mock to już trochę trzeba posiedzieć. 

Hmm, z mockowaniem nie mam jeszcze doświadczenia, ale czy zmockowanie userDAO nie spowoduje, że żadne operację na bazie danych się nie wykonają? Ja tu głównie testuję komunikację z bazą danych - i tak wiem, nie można nazwać tego testami jednostkowymi. Niech będzie, że są to integracyjne :D

I tu masz taki przypadek, zdecydowanie za długi ten test. Po pierwszy jest zły. Jeden test, bada jedną rzecz i wbij to sobie do głowy.  

Miałem z tym własnie dylemat, początkowo zrobiłem to jako osobne testy, ale połączyłem to w jeden bo każdy z nich wyglądam niemal identycznie - tyle, że z dopisaną jedną linijką. Chciałem uniknąć powtarzania kodu. 

Powiedzmy, że mam tych 10000 testów i ten jeden się nie wykona, i na który assert mam patrzeć? tam gdzie się równa , tam gdzie sprawdzam assercję. Nie wiem. Po drugie jest za bardzo zależna.  

Nie za bardzo rozumiem. Przecież kod się wywala na konkretnej asercji więc od razu wiadomo co gdzie się stało.


Co do Javascript, to za pewne mówisz o event bubbling/event delegation, tak? W jakim sensie te foreach są brzydkie :D?


Jeśli skorzystam z event delegation to za każdym razem będę musiał sprawdzać jaki element został kliknięty tak? Czy to nie jest o wiele brzydsze? :D Co jest złego w nadaniu listenerów obiektom z góry?

Jeszcze raz dzięki za poświęcony czas i liczę na to, że jeszcze trochę popiszemy ;)

komentarz 25 września 2017 przez ShiroUmizake Nałogowiec (46,300 p.)

Apkę robię sam, główne źródła to dokumentacja lub Stack Overflow. Czasem jakiś przyład na blogu.

To nice. Choć za wielkie doświadczenie z springiem nie miałem, to wiedziałem co dana rzecz springa robi :)

Hmm, InteliJ podczas wstrzykiwania zależności bezpośrednio do pól przez 

Bo powineś to robić przez klasyfikatory dostępu ;d, a dlaczego? Bo możesz między innymi sprawdzić poprawność danych :), bądż zablokować niektóre dane, że nie można je zmienić zewnątrz np: dane dla connectora bądż driveraSQL.

zastosowałem automatyczne wykonanie roboty przez InteliJ to dodał mi modyfikator final. Sam się zastanawiam czemu, musi być jakiś powód :D Może ty się domyślasz?

Szczerze nie wiem. By nie rozszerzać prototypu obiektu bądż nie umożliwić podmianę całego obiektu. Tak tylko strzelam.

Okey, mniej więcej rozumiem różnice między SessionFactory i EntityManager, widzę jakie mają zalety, jednak w tym projekcie nie ma nic przeciwko SessionFactory hmm? Czy zawsze powinno się preferować EntityManager?

To są dwie różne rzeczy ^^ . SessionFactory rozszerza obiekt Session (po porównaniu do obiektu Session z JAVAEE)

http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpSession.html

Zauważ, że tutaj jest obiekt Session, ale tu nie ma żadnych metod, sprawdzająych bazę danych, czy dany użytkownik ma dostęp. Używając z  javax obiektu httpSession , my musimy sami utworzyć kontroler autoryzacji. A w sessionFactory to robi za ciebie, a właściwie zwraca obiekt currentSession na którym możesz wykonywać query. Ale sessionFactory dotyczy się tylko user, nie zapytasz się tabelę "Product". A używając EM

możesz bardzo w prosty sposób pytać  się o całe db :).

Tu masz przykład, prostej domeny  :)

https://github.com/PatrykMaternicki/personRest/blob/master/src/main/java/domain/Person.java

Zauważ, że na górze mam zmapowane querySQL.

a tu serwis obsługujący zasoby i powiedzmy, że chce wyciągnąć wszystkich użytkowników.

https://github.com/PatrykMaternicki/personRest/blob/master/src/main/java/rest/services/PersonResource.java

List<Person> result = em.createNamedQuery("Person.all" , Person.class).getResultList();

Tutaj jest przykładowa implementacja REST, ale myśle, że wytluaczyłem różnice między sessionFactory, a EM. Choć myśle, jakby tobie się udało dostać do danych z currentSession, to również w EM mógłbyś użyć.Ufff... się rozpisałem ;d.

A czy zawsze warto używać EM? to zależy, czy masz go dostępnego :D. Dla mnie jest to spore ułatwienie.

Lecimy dalej.

Setup to znaczy co? Masz na myśli, ze przed każdym testem są tworzone potrzebne obiekty? Jeśli tak, to to co zakomentowałeś czyli addUser() jest "setupem". Jest oznaczone z @Before, więc wykonuje się przed każdym tekstem. Czy źle Cię zrozumiałem?

Faktycznie, masz before nie spotrzegłem ;d

Hmm, z mockowaniem nie mam jeszcze doświadczenia, ale czy zmockowanie userDAO nie spowoduje, że żadne operację na bazie danych się nie wykonają? Ja tu głównie testuję komunikację z bazą danych - i tak wiem, nie można nazwać tego testami jednostkowymi. Niech będzie, że są to integracyjne :D

Odpal wielokrotnośc na 10000 i idż sobie kawusię zaparzyć xd. Mówię poważnie. A po drugie, zrobić test zachowania bazy danych nie trzeba mieć "fizycznej bazy danych"

Znalazłem coś takiego np: 

https://stackoverflow.com/questions/12066457/how-to-mock-sessionfactory-or-session-by-powermockito-in-a-project-using-spring

Tu masz szerzej o testowaniu jak dobrze pamiętam z testowaniem db było tutaj:

https://www.youtube.com/watch?v=QvAeRl1Plxo&t=1329s

Miałem z tym własnie dylemat, początkowo zrobiłem to jako osobne testy, ale połączyłem to w jeden bo każdy z nich wyglądam niemal identycznie - tyle, że z dopisaną jedną linijką. Chciałem uniknąć powtarzania kodu. 

A co nagle w jednym z nich coś zmienie, np: jakieś pole , bądż dopiszę nowy metody już takie same nie będą.

Nie za bardzo rozumiem. Przecież kod się wywala na konkretnej asercji więc od razu wiadomo co gdzie się stało.

Aż ciekawości sprawdzę i się mylisz. Mamy, taką o to klasę. 

public class Calculator {

	private int a;
	private int b;
	
	public Calculator(int a, int b) {
		super();
		this.a = a;
		this.b = b;
	}
	
	public int add(){
		return a + b;
	}
	
	public boolean isEqual(int c){
		int sum = a + b;
		return a==b;
	}
	
	public boolean isAEqualZero(){
		return a == 0;
	}
}

Prosta klasa, prosty kalkulator

A teraz testy do tej klasy:

public class AppTest {

	private Calculator calculator;
	@Before
	public void setUp(){
		calculator = new Calculator(3,4);
	}
	
	@Test
	public void should_be_return_seven(){
		assertEquals(7,calculator.add());
		
	}
	@Test
	public void testAll(){
		assertEquals(6,calculator.add());
		assertEquals(true,calculator.isAEqualZero() );
		assertEquals(false,calculator.isEqual(100));
	}
	
    @Test
    public void testApp() {
        App app = new App();
    }
}

Jak możesz zauwyżyć że żadna assercja nie przejdzie testów z metody testAll. Mamy nowego pracownika zielony totalnie, co mu powie metoda testAll? Owszem, że coś jest nie tak z kalkulatorem ale co, mi ta metoda nic nie mówi, nie wiem co testuje. should_be_return_serven myśle, że o wiele więcej mu powie, że wynik oczekiwany to 7.

Zaczarujmy, zmieńmy wartości do testów.

public void testAll(){
		assertEquals(7,calculator.add());
		assertEquals(false,calculator.isAEqualZero() );
		assertEquals( true,calculator.isEqual(100));
	}

Failed tests:   testAll(io.minh.basejava.AppTest): expected:<true> but was:<fals
e>

Nie za wiele mi to mówi, nie wiem dlaczego to nie wypaliło etc.

Ok, owszem, możesz je opisać, ale czasami może być dłuższy niż sam test :D

assertTrue ('User he may got authorize to change System priviliges, 
when he using extarnal application and connect SSH ports. System.AuthorizeApplication.UI.UiAdministrator.changePrivligeles());

Podsumuwując mój wywód na temat testów, warto każdy pisać osobno gdyż: opis nie zawsze jest najelpszym pomysłem, po drugie gdy opgramowanie się rozwija, możemy będziemy chcieli dodać funkcjonalności, zmienić typy pól, nagle testy nie pykną bądz w ogóle się wysypią. Po trzecie dla ułatwienia dla cb (gdy wrócisz do projektu po roku, uwierz mi, że nie będziesz tak dokładnie pamiętał co która klasa robi, a tymbardziej jakaś metoda crud. Po czwarte by kolejna osoba mogła wejść w kod.

Mam nadzieję, że mój wywód ma jakiś sens :).

Ufff... Kolejny punkt. 

Co do Javascript, to za pewne mówisz o event bubbling/event delegation, tak? W jakim sensie te foreach są brzydkie :D?

Gdy nagle tworzy ci coś takiego ;d. 

https://github.com/PatrykMaternicki/tic-tac-toe/blob/master/public_html/JS/Game.js

nodesFields.forEach(
              (node) => node.addEventListener(
                        'click',
                        () => {
                           
                                if (this.gameControler.roundIsEnd()){
                                    return;
                                }
                                this.startTurn(node);
                                  if (this.gameControler.getNowTurn() >= 4){
                                      if (this.gameControler.getNowTurn() == 9 && !this.gameControler.roundIsEnd()){
                                    this.sceneMenager.addToSceneTie();
                                    window.setTimeout(
                                                        () =>{
                                                            this.sceneMenager.removeSceneWhoWin();
                                                            this.playAgain(document.querySelectorAll("td"));
                                                               },
                                                              2000
                                                        );
                                    return;
                                        }
                                        
                                    if (this.gameControler.isWinner(document.querySelectorAll("td"))){
                                                this.sceneMenager.addToSceneWhoWin(
                                                        this.gameControler.getWinnerPlayer(),
                                                        this.configMenager.getAssets()
                                                        );
                                                this.configMenager.increaseWinStreak(
                                                        this.gameControler.getWinnerPlayer()
                                                        );
                                                this.configMenager.increaseRounds();
                                                if (this.gameControler.weGetWinnerGame(
                                                      this.configMenager.getPlayer1().getWinRound(),
                                                      this.configMenager.getPlayer2().getWinRound(),
                                                      this.configMenager.getMaxRound()
                                                    )
                                                    ){
                                                    this.checkAndAddWhoWin();
                                                    return;
                                                    }
                                                this.sceneMenager.renderElementsGame(
                                                        this.gameControler.getWinnerPlayer(),
                                                        this.configMenager.getPlayer1(),
                                                        this.configMenager.getPlayer2(),
                                                        this.configMenager.getNowRound()
                                                        );
                                                window.setTimeout(
                                                        () =>{
                                                            this.sceneMenager.removeSceneWhoWin();
                                                            this.playAgain(document.querySelectorAll("td"));
                                                               },
                                                              2000
                                                        );
                                                
                                                
                                    }
                                  }
                                     
                            }
                            )
                    );

Ale tak to jest jak czas goni a ty masz za 2 dni oddać xd.

Jeśli skorzystam z event delegation to za każdym razem będę musiał sprawdzać jaki element został kliknięty tak? Czy to nie jest o wiele brzydsze? :D Co jest złego w nadaniu listenerów obiektom z góry? 

Tak i nie , zależy od kontekstu wywołowania.Przykład. 

https://codepen.io/shiroUmizake/pen/ZXBwbr

Nie ma nic złego z nadawania z góry, byle się nie skończyło tak jak powyższym przykładzie (O dziwo tamto działa ;d)

 

 

komentarz 25 września 2017 przez Codeboy Stary wyjadacz (12,120 p.)

Ale sessionFactory dotyczy się tylko user, nie zapytasz się tabelę "Product". 

O jakim ograniczeniu mówisz? Mogę zrobić Query na dowolny zmapowany obiekt. Chyba, że tobie chodzi właśnie o nie zmapowane obiekty? Na razię nie widzę potrzeby implementowania EM, ale będę miał to w głowie ;)

Odpal wielokrotnośc na 10000 i idż sobie kawusię zaparzyć xd. Mówię poważnie. A po drugie, zrobić test zachowania bazy danych nie trzeba mieć "fizycznej bazy danych"

Okey, skupię się teraz na testach i mockowaniu. Dzięki za źródła. Jeśli jeszcze  masz coś  dobrego na temat testów i mockowania to podeślij ;) 

Failed tests:   testAll(io.minh.basejava.AppTest): expected:<true> but was:<fals 
e>

Nie za wiele mi to mówi, nie wiem dlaczego to nie wypaliło etc.

Yyy czego ty używasz? :D W intelij mam wszystko przejrzyście napisane co się stało:
 

java.lang.AssertionError: 
Expected :6
Actual   :7
    at org.junit.Assert.fail(Assert.java:88)
    at org.junit.Assert.failNotEquals(Assert.java:834)
    at org.junit.Assert.assertEquals(Assert.java:645)
    at org.junit.Assert.assertEquals(Assert.java:631)
    at todolist.daos.AppTest.testAll(AppTest.java:25)

Assertion error w metodzie testAll w linijce 25. Miało być 6 a jest 7 :D ??? Co jest nie tak ^^ A dodatkowe message to chyba nic złego ;)

Oczywiście rozumiem co chcesz mi przekazać, ale mam tu kilka wątpliwości tak jak wcześniej. No bo jak mam przetestować pojedyncze dodanie do todolisty taska i zmienienie go np na "done"? Przecież po drodze przejdę przez wszystkie kluczowe operacje, które muszą być testowane, addUser -> AddTodoList -> AddTask -> setTaskAsDone. Więc w tym teście tak czy siak zostanie wszystko przetestowane, więc po co mam osobno sprawdzić dodawanie listy czy taska? Gdyby te testy jeszcze się odpalały po kolei to by było inaczej, można by z każdym testem iść o krok dalej, ale tak się nie da, bo odpalają się randomowo :<

Gdy nagle tworzy ci coś takiego ;d. 

https://github.com/PatrykMaternicki/tic-tac-toe/blob/master/public_html/JS/Game.js

surprise

Jak będziesz miał czas to śmiało dokładaj dalsze komentarze o których mówileś ;)

komentarz 26 września 2017 przez ShiroUmizake Nałogowiec (46,300 p.)

 jakim ograniczeniu mówisz? Mogę zrobić Query na dowolny zmapowany obiekt. Chyba, że tobie chodzi właśnie o nie zmapowane obiekty?

Yeah. 

Okey, skupię się teraz na testach i mockowaniu. Dzięki za źródła. Jeśli jeszcze  masz coś  dobrego na temat testów i mockowania to podeślij ;) 

JUG i Confitura to są świetne zasoby wiedzy o JAVIE na trochę wyższym poziomie :)

Yyy czego ty używasz? :D W intelij mam wszystko przejrzyście napisane co się stało:

Ten test był banalnie prosty, chciałem Ci pokazać tylko przykład. Że to co dla ciebie jest oczywiste nie do końca musi być oczywiste dla nowego członka zespołu. 

j. No bo jak mam przetestować pojedyncze dodanie do todolisty taska i zmienienie go np na "done"?

Mock :) ja chcę przetestować coś dzieje jedynie. Jak będziesz chciał mogę Ci podać przykład póżniej jak wykorzystać verify().

rzecież po drodze przejdę przez wszystkie kluczowe operacje, które muszą być testowane, addUser -> AddTodoList -> AddTask -> setTaskAsDone

Możesz mockować, masz tam taką metodę then/when. 

http://www.baeldung.com/mockito-behavior

Więc w tym teście tak czy siak zostanie wszystko przetestowane, więc po co mam osobno sprawdzić dodawanie listy czy taska? 

Przykład życia, miałem kiedyś problem, że mój servlet tak z dupy wysypał się na czymś, wskazując na nullPointException czyli coś nie zostało zainicjonowane. A wtedy też podchodziłem do tych testów, tak mech... po co wszystko testować. Ale ćwiczeniowiec kazał robić do wszystkiego testy. No i się męczę męcze 3 dni szukałem. Aż w końcu stwierdziłem, a zobaczmy co testy powiedzą. I testy mi odpowiedziały, że miałem błędne ustawienia w któryś accessRules, przez to sypał authorizeControler, a przez to psuła się obiekt Action(był pusty) i związku z tym metoda doAccess(), a że nie nic wykonał to filter się sypał. Doszedłeś do tego? :)

A był to obiekt typowo domenowy :) i tam był problem. Masz odpo

Pamiętaj przy mockowaniu nie interesuje mnie zbytnio czy moim user jest ciociaJadzia, wyjek Zbigniew ja chcę zbadać jedynie jak się zachowa. 

 

Podobne pytania

0 głosów
3 odpowiedzi 266 wizyt
pytanie zadane 1 grudnia 2020 w Java przez ariva6152 Użytkownik (570 p.)
0 głosów
1 odpowiedź 231 wizyt
pytanie zadane 1 sierpnia 2017 w Java przez lewy Obywatel (1,260 p.)
0 głosów
1 odpowiedź 145 wizyt
pytanie zadane 27 maja 2018 w Nasze projekty przez kamil159 Nowicjusz (180 p.)

92,576 zapytań

141,426 odpowiedzi

319,650 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...