рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░ред
MockMvc рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдореБрдЭреЗ Habr рдкрд░ рдЗрд╕рдХреЗ рд╕рдВрджрд░реНрднреЛрдВ рдХреА "
рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ " рдХрд╛ рдкрддрд╛ рдЪрд▓рд╛ред рдореИрдВ рдЗрд╕ рдЕрдВрддрд░ рдХреЛ рднрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛, рдЦрд╛рд╕рдХрд░ рдЬрдм рд╕реЗ рд╣рдорд╛рд░реЗ
рдХреЙрдиреНрдЯреИрдХреНрдЯ рдореИрдирдЬрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдкрд░реАрдХреНрд╖рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рддреЛ, рдкрд╛рда рдХрд╛ рдореБрдЦреНрдп рд╡рд┐рд╖рдп рдирд┐рдпрдВрддреНрд░рдХ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдЬреЛрдбрд╝рдирд╛ рд╣реИред рдПрдХ рдмреЛрдирд╕ рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдо рдлреИрд╢рдиреЗрдмрд▓,
"рдиреЛ-рдПрдХреНрд╕рдПрдордПрд▓" рддрдХрдиреАрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдРрд╕рд╛ рдХрд░реЗрдВрдЧреЗред
рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕рдВрд░рдЪрдирд╛ рдЕрджреНрдпрддрди
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВред рд╕реНрдкреНрд░рд┐рдВрдЧрдлреНрд░реИрдорд╡рд░реНрдХ рдХреЛ рдЕрдм 3.2.1 рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдореЗрдВ рдкреНрд░рддрд┐рд╖реНрдард┐рдд MockMvc рд╢рд╛рдорд┐рд▓ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдЕрдкрдбреЗрдЯ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рд╕реНрдкреНрд░рд┐рдВрдЧ рд╕реБрд░рдХреНрд╖рд╛ рдереЛрдбрд╝рд╛ рдкреАрдЫреЗ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ (рд▓рдЧрднрдЧ) рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред рд╣рд╛рдЗрдмрд░рдиреЗрдЯ рд╕рдВрд╕реНрдХрд░рдг рднреА 4.1.9 рддрдХ рдмрдврд╝рд╛ред рдкреВрд░реНрдг рдкрд░рд┐рдпреЛрдЬрдирд╛ рдлрд╝рд╛рдЗрд▓
рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА (рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рд▓рд┐рдВрдХ) рдореЗрдВ рдорд┐рд▓ рд╕рдХрддреА рд╣реИред
рд╣рд╛рдЗрдмрд░рдиреЗрдЯ рдХреЗ рд╕рдВрд╕реНрдХрд░рдг 4 рдореЗрдВ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
data.xml
рдлрд╝рд╛рдЗрд▓ рдХреЗ рдереЛрдбрд╝рд╛ рд╢реЛрдзрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЖрдкрдХреЛ рд╕рдВрдХреБрд▓ рдирд╛рдо
sessionFactory
рдореЗрдВ 3 рд╕реЗ 4 рдмрджрд▓рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ,
sessionFactory
рдореЗрдВ
configLocation
рдФрд░
configurationClass
рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╣рдЯрд╛ рджреЗрдВ рдФрд░ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп
configLocation
рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдЬреЛрдбрд╝реЗрдВ, рдЬрд╣рд╛рдВ рд╣рд╛рдЗрдмрд░рдиреЗрдЯ рдореИрдкрд┐рдВрдЧ рд╕реЗ рд╣рд╛рдЗрдмрд░рдиреЗрдЯ рдореИрдкрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рд╡рд░реНрдЧ рдкреИрдХреЗрдЬреЛрдВ рдХреА рд╕реВрдЪреА рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рд╣реИред рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЛ рд╕реНрд╡рдпрдВ рд╣рдЯрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд╣рдореЗрдВ рдЕрдм рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк,
sessionfactory
рдлреЙрд░реНрдо рд▓реЗрдЧреА:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan"> <list> <value>net.schastny.contactmanager.domain</value> <value>com.acme.contactmanager.domain</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">create-drop</prop> <prop key="hibernate.dialect">${jdbc.dialect}</prop> <prop key="hibernate.connection.charSet">UTF-8</prop> </props> </property> </bean>
рд╣рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЗрд╕рд▓рд┐рдП рд╣рдо
src/test/resources
рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдмрдирд╛рддреЗ рд╣реИрдВ, рдЙрд╕рдореЗрдВ
security.xml
testdb.properties
security.xml
рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЙрдкреА рдХрд░рддреЗ рд╣реИрдВ,
testdb.properties
рдмрдирд╛рддреЗ рд╣реИрдВ - рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд▓рд┐рдП рдЧреБрдг рдлрд╝рд╛рдЗрд▓ред рдЖрдк рдЗрд╕рдХреЗ рдмрд┐рдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рд╕реЗ, рд╢реИрдХреНрд╖рд┐рдХ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП, рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдЖрдк рдмрд╛рд╣рд░ рд╕реЗ рдбрд┐рдмреНрдмреЗ рдореЗрдВ рдЧреБрдг рдХреИрд╕реЗ рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдлрд╝рд╛рдЗрд▓ рд╕рд╛рдордЧреНрд░реА
db.user.name=sa db.user.pass=
рднрдЧрд╡рд╛рди рдЬрд╛рдирддрд╛ рд╣реИ рдХреНрдпрд╛, рд▓реЗрдХрд┐рди рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рдпрд╣ рдХрд░реЗрдЧрд╛ред рд╣рдо
log4j.xml
рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕ рдкрд░ рд╕рднреА рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рд╕рд╛рдеред рд╣рдо рд╕реНрд░реЛрдд рдХреЛрдб рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред
src/test/groovy
рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛, рдкреИрдХреЗрдЬ
com.acme.contactmanager.test
рдЖрджреЗрд╢ рдкрдВрдХреНрддрд┐ рд╕реЗ рдЕрд╕реЗрдВрдмрд▓реА рдХреЗ рджреМрд░рд╛рди рд╣рдорд╛рд░реЗ рдЦрд╛рдВрдЪреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП, рдирд┐рд░реНрдорд╛рдг-рд╕рд╣рд╛рдпрдХ-рдорд╛рд╡реЗрди-рдкреНрд▓рдЧрдЗрди рдХреЛ pb.ml рдкрд░ рдЬреЛрдбрд╝реЗрдВ
рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд╕рдВрдд рд╡рд┐рдиреНрдпрд╛рд╕
рдПрдХ рд╕реНрдкреНрд░рд┐рдВрдЧ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ
TestConfig.groovy
@Configuration @ComponentScan(['net.schastny.contactmanager.dao', 'com.acme.contactmanager.dao', 'net.schastny.contactmanager.web', 'net.schastny.contactmanager.service']) @PropertySource('classpath:testdb.properties') @ImportResource('classpath:security.xml') @EnableTransactionManagement class TestConfig {
рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рдирд╛рдо рдЕрдкрдиреЗ рд▓рд┐рдП рдмреЛрд▓рддреЗ рд╣реИрдВ:
- рдпрд╣ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╣реИ
- рдШрдЯрдХреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреИрдХреЗрдЬреЛрдВ рдореЗрдВ рджреЗрдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП (рдпрд╛рдж рд░рдЦреЗрдВ: рдпреЗ рдЦрд╛рдВрдЪреЗ рд╣реИрдВ рдФрд░ рд╕рд░рдгреА рдХреЛ рдЪреМрдХреЛрд░ рдХреЛрд╖реНрдардХ рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ)
- testdb.properties
testdb.properties
рдлрд╝рд╛рдЗрд▓ рд▓реЛрдб рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ security.xml
рдмрд╛рд░реЗ рдореЗрдВ рдордд рднреВрд▓рдирд╛ред security.xml
- рдФрд░ рд╣рд╛рдВ, рд╣рдореЗрдВ рд▓реЗрдирджреЗрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА
рд╡реИрд╕реЗ, рд▓реЗрди-рджреЗрди рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВред DAO рдФрд░ рд╕реЗрд╡рд╛ рд╡рд░реНрдЧреЛрдВ рдХреЗ рд▓рд┐рдП, рдЗрдВрдЯрд░рдлреЗрд╕ рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЕрд▓рдЧ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░ рдЖрдк рдЦреБрдж рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд░реНрдЧ рддрдХ рд╕реАрдорд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдПрдиреЛрдЯреЗрд╢рди рдореЗрдВ рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ рдХрд┐ рдкреНрд░реЙрдХреНрд╕реАрдЯрд╛рд░реНрдЯ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЕрдиреНрдпрдерд╛ рд╕рдорд╕реНрдпрд╛рдПрдВ @EnableTransactionManagement(proxyTargetClass = true)
: @EnableTransactionManagement(proxyTargetClass = true)
рдЕрдЧрд▓рд╛ред
testdb.properties
рд╕реЗ рд╡рд░реНрдЧ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рд╕рд╛рде
@Value
рдЧреБрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрд╛рдЗрдВрдб рдЧреБрдг
class TestConfig { @Value('${db.user.name}') String userName @Value('${db.user.pass}') String userPass
LocalSessionFactoryBean
рдЬреЛрдбрд╝реЗрдВ, рдЬрд╣рд╛рдВ рд╣рдо рдкреНрд░рд╛рдкреНрдд рдЧреБрдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рдпрд╣рд╛рдВ рд╣рдо рдкрд░рд┐рдЪрд┐рдд
packagesToScan
рджреЗрдЦрддреЗ
packagesToScan
@Bean public LocalSessionFactoryBean sessionFactory() { LocalSessionFactoryBean bean = new LocalSessionFactoryBean() bean.packagesToScan = [ 'com.acme.contactmanager.domain', 'net.schastny.contactmanager.domain'] as String[] Properties props = new Properties() props."hibernate.connection.driver_class" = "org.h2.Driver" props."hibernate.connection.url" = "jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE;DB_CLOSE_ON_EXIT=FALSE" props."hibernate.connection.username" = userName props."hibernate.connection.password" = userPass props."hibernate.dialect" = "org.hibernate.dialect.H2Dialect" props."hibernate.hbm2ddl.auto" = "create-drop" props."hibernate.temp.use_jdbc_metadata_defaults" = "false" bean.hibernateProperties = props bean }
рдпрд╣ рдмрд╛рдд hibernate.temp.use_jdbc_metadata_defaults = false
рддрдм рдорджрдж рдХрд░рддреА рд╣реИ рдЬрдм рдпрд╣ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рдзреАрдорд╛ рдХрд░ рджреЗрддреА рд╣реИ
рдФрд░ рдЕрдВрдд рдореЗрдВ, рд╣рдорд╛рд░реЗ рд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ "рдХреЗрдХ рдкрд░ рдЪреЗрд░реА"
HibernateTransactionManager
рд╣реЛрдЧрд╛
@Bean public HibernateTransactionManager transactionManager() { HibernateTransactionManager txManager = new HibernateTransactionManager() txManager.autodetectDataSource = false txManager.sessionFactory = sessionFactory().object txManager }
рдореИрдВ рджреЛрд╣рд░рд╛рддрд╛ рд╣реВрдВ - xml рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рд╡рд┐рдиреНрдпрд╛рд╕ рдкреБрд░рд╛рдирд╛ рд╣реА рд░рд╣рд╛ рд╣реИред рдпрд╣ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗрд╡рд▓ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред
рдкрд░реАрдХреНрд╖рдг рд╢реБрд░реВ рдХрд░реЗрдВ
рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдм рдПрдХ рдХрд╣рд╛рд╡рдд рдереА, рдпрд╣ рдПрдХ рдкрд░реА рдХрдерд╛ рдХрд╛ рд╕рдордп рдерд╛ред рдпрд╣ рдЙрдореНрдореАрдж рдХрд░рдирд╛ рддрд░реНрдХрд╕рдВрдЧрдд рд╣реИ рдХрд┐ MockMvc рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ 3 рдЪрд░рдг рд╣реЛрддреЗ рд╣реИрдВ: рдПрдХ рдирдХрд▓реА рд╡рд╕реНрддреБ рдХрд╛ рдирд┐рд░реНрдорд╛рдг, рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ HTTP рдЕрдиреБрд░реЛрдз рднреЗрдЬрдирд╛ рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдирд╛ред рдкрд╣рд▓реЗ рдЪрд░рдг рдХреЗ рд▓рд┐рдП - рдПрдХ рдирдХрд▓реА рд╡рд╕реНрддреБ рдХрд╛ рдирд┐рд░реНрдорд╛рдг - рд╣рдо WebApplicationContext рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рдмрд┐рд▓реНрдбрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
MockMvcTest.groovy
рдирд╛рдо рд╕реЗ рдПрдХ рд╡рд░реНрдЧ рдмрдирд╛рдПрдВ
@RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(classes = [ TestConfig.class ] ) class MockMvcTest { @Autowired WebApplicationContext wac MockMvc mockMvc @Before public void setup() { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).dispatchOptions(true).build() } }
рдЕрдкрдорд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИред рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХреБрдЫ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдорд╛рд░реЗ рдирд┐рдпрдВрддреНрд░рдХ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐
home()
рд╡рд┐рдзрд┐, рдЬрд╣рд╛рдВ рдПрдХ рд╕рд░рд▓ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢ рд╣реИ, рдПрдХ рдкрд░реАрдХреНрд╖рдг рдкрд░реАрдХреНрд╖рд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдЪреНрдЫрд╛ рдЙрдореНрдореАрджрд╡рд╛рд░ рд╣реИред
@RequestMapping("/") public String home() { return "redirect:/index"; }
рджрд░рдЕрд╕рд▓, рд╣рдо рд▓рд┐рдЦрддреЗ рд╣реИрдВ
@Test public void home() { MockHttpServletRequestBuilder request = MockMvcRequestBuilders.get("/") ResultActions result = mockMvc.perform(request) result.andExpect(MockMvcResultMatchers.redirectedUrl("/index")) }
рд▓рдЧрднрдЧ рдХреЛрдИ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ:
- MockMvcRequestBuilders.get ("/") рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╣рдореЗрдВ url рдХреЗ рд▓рд┐рдП GET рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдПрдХ рд░реИрдкрд░ рдорд┐рд▓рддрд╛ рд╣реИ "/"
- mockMvc.perform (рдЕрдиреБрд░реЛрдз) рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИ
- рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдо рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдЗрдЪреНрдЫрд┐рдд URL рдкрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рди рд╡рд╛рдкрд╕ рдЖ рдЧрдпрд╛ рд╣реИ
andExpect()
рдлрд╝рдВрдХреНрд╢рди рдкрд░рд┐рдгрд╛рдо рдХреА рдЬрд╛рдБрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢рд╛рдирджрд╛рд░ рдЕрд╡рд╕рд░ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдпрд╣рд╛рдБ andExpect()
рдЙрджрд╛рд╣рд░рдг рд╣реИрдВ рдЬреЛ рдЕрдкрдиреЗ рдХрд╛рдо рдХрд╛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рдЪрд╛рд░ рджреЗрддреЗ рд╣реИрдВ:
mockMvc.perform(get("/person/1")) .andExpect(status.isOk()) .andExpect(content().mimeType(MediaType.APPLICATION_JSON)) .andExpect(jsonPath("$.person.name").equalTo("Jason")); mockMvc.perform(post("/form")) .andExpect(status.isOk()) .andExpect(redirectedUrl("/person/1")) .andExpect(model().size(1)) .andExpect(model().attributeExists("person")) .andExpect(flash().attributeCount(1)) .andExpect(flash().attribute("message", "success!"));
рд╣рдо рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд╣реБрд░реНрд░реЗ, рдкрд╣рд▓рд╛ рдкрд░реАрдХреНрд╖рдг рддреИрдпрд╛рд░ рд╣реИред рдЖрдЧреЗ рдХреНрдпрд╛ рд╣реИ? рд╕рдВрдкрд░реНрдХ рд╕реВрдЪреАред
@RequestMapping("/index") public String listContacts(Map<String, Object> map) { map.put("contact", new Contact()); map.put("contactList", contactService.listContact()); map.put("contactTypeList", contactService.listContactType()); return "contact"; }
рд╕рднреА рд╕рдорд╛рди GET рдЕрдиреБрд░реЛрдз, рд╣рдо рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рдорд╛рдирдЪрд┐рддреНрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕реЗ рднрд░рддреЗ рд╣реИрдВ рдФрд░ рдирд╛рдо рджреГрд╢реНрдп рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ GET рдЕрдиреБрд░реЛрдз рдХреИрд╕реЗ рднреЗрдЬреЗрдВ, рдпрд╣ рдХреЗрд╡рд▓ рдкрд░рд┐рдгрд╛рдо рдХреА рдЬрд╛рдВрдЪ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╣рддрд╛ рд╣реИред рд╣рдо рдПрдХ рджреВрд╕рд░реА рдкрд░реАрдХреНрд╖рд╛ рд▓рд┐рдЦ тАЛтАЛрд░рд╣реЗ рд╣реИрдВред
@Test public void index() { ResultActions result = mockMvc.perform(MockMvcRequestBuilders.get("/index")) result.andExpect(MockMvcResultMatchers.view().name("contact")) .andExpect(MockMvcResultMatchers.model().attributeExists("contact")) .andExpect(MockMvcResultMatchers.model().attributeExists("contactList")) .andExpect(MockMvcResultMatchers.model().attributeExists("contactTypeList")) }
рдлрд┐рд░ рд╕реЗ, рдПрдХ рднреА рдЕрддрд┐рд░рд┐рдХреНрдд рд▓рд╛рдЗрди рдирд╣реАрдВред рдЕрдиреБрд░реЛрдз рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдордиреЗ рдирд╛рдо рджреГрд╢реНрдп рдХреА рдЬрд╛рдБрдЪ рдХреА, рдЬрд┐рд╕реЗ рдЙрд╕рдиреЗ рд╣рдореЗрдВ рд▓реМрдЯрд╛ рджрд┐рдпрд╛, рдФрд░ рдЬрд╛рдБрдЪ рдХреА рдХрд┐ рдореЙрдбрд▓ рдХреЗ рд╕рднреА рдЧреБрдг рдореМрдЬреВрдж рд╣реИрдВред рдЗрди рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддреГрдд рдЕрдзреНрдпрдпрди рдХреЗ рд▓рд┐рдП, рдЖрдк -Return () рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ MvcResult рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рд▓рд┐рдВрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
MvcResult mvcResult = result.andReturn() assert mvcResult.modelAndView.model.contactTypeList.size() == 3
рдЕрдм рддрдХ, рд╕рдм рдХреБрдЫ рдареАрдХ рдЪрд▓ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрднреА рднреА рдмрд╣реБрдд рдХрд╛рдо рдХрд░рдирд╛ рдмрд╛рдХреА рд╣реИред рдпрд╣ рд╣рдорд╛рд░реА рд╕реВрдЪреА рдореЗрдВ рдХреБрдЫ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред рдирд┐рдпрдВрддреНрд░рдХ рд╡рд┐рдзрд┐ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреА рд╣реИ:
@RequestMapping(value = "/add", method = RequestMethod.POST) public String addContact(@ModelAttribute("contact") Contact contact, BindingResult result) { contactService.addContact(contact); return "redirect:/index"; }
рдЕрдВрдд рдореЗрдВ, рдкреЛрд╕реНрдЯ рд╡рд┐рдзрд┐, рдкреНрд▓рд╕ рдЕрднреА рднреА рднрдпрд╛рдирдХ
@ModelAttribute Contact contact
рдкреИрд░рд╛рдореАрдЯрд░ред рд▓реЗрдХрд┐рди рд╕рдм рдХреБрдЫ рдЗрддрдирд╛ рдмреБрд░рд╛ рдирд╣реАрдВ рд╣реИред "Mockmvc ModelAttribute" рдХреЗ рд▓рд┐рдП рдПрдХ рддреНрд╡рд░рд┐рдд Google рдЦреЛрдЬ рднреА
рдкрд░рд┐рдгрд╛рдо рджреЗрддреА рд╣реИред рдЗрд╕ рддрд░рд╣ рдХреА рдореИрдкрд┐рдВрдЧ рдХреЛ рдХреЗрд╡рд▓ рдХреНрд╡реЗрд░реА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдПрдХ рд╕реЗрдЯ рд╕реЗ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдХреНрд╡реЗрд░реА рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрдиреЗ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рд╣реИ:
param(Stirng name, String... values)
ред рд╣рдо рд▓рд┐рдЦрддреЗ рд╣реИрдВ
@Autowired ContactService contactService @Test public void add() {
рдЦреИрд░, рдЕрдВрддрд┐рдо рд╡рд┐рдзрд┐ рдмрдиреА рд╣реБрдИ рд╣реИ - рд╣рдЯрд╛рдПрдВ ()ред
@RequestMapping("/delete/{contactId}") public String deleteContact(@PathVariable("contactId") Integer contactId) { contactService.removeContact(contactId); return "redirect:/index"; }
@PathVariable
рдХрд░рдирд╛ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ, рдмрд╕ рдЗрд╕реЗ URL рдореЗрдВ рдЬреЛрдбрд╝реЗрдВред
@Test public void delete() {
рдпрд╣ рд╕рдм рд╣реИ, рд╕рднреА рд╡рд┐рдзрд┐рдпрд╛рдБ рд╕реНрд╡рдд: рдкрд░реАрдХреНрд╖рдг, рдЪреАрдпрд░реНрд╕ рд╕реЗ рдЖрдЪреНрдЫрд╛рджрд┐рдд рд╣реИрдВ! рдпрд╛ рдЪреАрдпрд░реНрд╕ рдирд╣реАрдВ? рдЪреМрдХрд╕ рдкрд╛рдардХ рдкреВрдЫреЗрдЧрд╛ - рд╕реБрд░рдХреНрд╖рд╛ рдХрд╛ рдХреНрдпрд╛! рдпрджрд┐ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдФрд░ рднреВрдорд┐рдХрд╛рдУрдВ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рд╣реИ, рддреЛ рд╣рдордиреЗ
security.xml
Xml рдХреЛ рдХреНрдпреЛрдВ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛! рдФрд░ рд╡рд╣ рд╕рд╣реА рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рдкрд╛рда рдХреЗ рддреАрд╕рд░реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдо рд╕реНрдкреНрд░рд┐рдВрдЧрд╕рд┐рдХреНрдпреЛрд░рд┐рдЯреА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдЬреЛрдбрд╝реЗрдВрдЧреЗред
рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдЬреЛрдбрд╝реЗрдВ
рдпрд╣ рдорд╛рдирдирд╛ тАЛтАЛрддрд░реНрдХрд╕рдВрдЧрдд рд╣реИ рдХрд┐ MockMvc рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ,
addFilter()
рдореЗрдВ рдПрдХ
addFilter()
рд╡рд┐рдзрд┐ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╣рдо
springSecurityFilterChain
рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдг рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдмрджрд▓реЗрдВ:
@Autowired FilterChainProxy springSecurityFilterChain @Before public void setup() { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac) .addFilter(springSecurityFilterChain)
рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ url рдПрдХреНрд╕реЗрд╕ рдХрд░рддреЗ рд╕рдордп рдПрдХ рдЕрдзрд┐рдХрд╛рд░ рдЬрд╛рдБрдЪ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рдХрд┐рд╕реА рддрд░рд╣ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдЕрдкрдирд╛ рдкрд░рд┐рдЪрдп рджреЗрдирд╛ рд╣реЛрдЧрд╛ред рдЪрд▓реЛ рдПрдХ "рдореЗрд░реЗ рдХрд╛рди рдХреЗ рд╕рд╛рде feint" рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ рдФрд░ рд╕реАрдзреЗ SecirityContextHolder рдХреЗ рд▓рд┐рдП рдореВрд▓реНрдп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВред
List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_USER"); Authentication auth = new UsernamePasswordAuthenticationToken("user1", "1111", authorities); SecurityContextHolder.getContext().setAuthentication(auth);
рдпрд╣ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд▓рдЧрддрд╛ рд╣реИ, рдРрдб () рдкрджреНрдзрддрд┐ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП ROLE_USER рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред Broads! рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛
DEBUG: org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /add; Attributes: [ROLE_USER] DEBUG: org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication. AnonymousAuthenticationToken@d4551ca6: Principal: guest; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication. WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS DEBUG: org.springframework.security.web.access.ExceptionTranslationFilter - Access is denied (user is anonymous); redirecting to authentication entry point
Granted Authorities: ROLE_ANONYMOUS
рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╣рдореЗрдВ рд╕рдВрдХреЗрдд рджреЗрддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдХрд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░реЗ
Granted Authorities: ROLE_ANONYMOUS
рдиреЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛ред рд▓реЗрдХрд┐рди рдореИрдВ рдЖрд╢реНрд╡рд╕реНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд▓реНрджрдмрд╛рдЬреА рдХрд░рддрд╛ рд╣реВрдВ - рдпрд╣рд╛рдВ рд╣рдорд╛рд░рд╛ рдХреЛрдИ рджреЛрд╖ рдирд╣реАрдВ рд╣реИ, рд╕реБрд░рдХреНрд╖рд╛ рд╕рдорд░реНрдерди
рдЕрднреА рддрдХ рдкрд░реАрдХреНрд╖рдгреЛрдВ
рдореЗрдВ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ред рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рд╢реБрд░реБрдЖрдд рдореЗрдВ рдореИрдВрдиреЗ рд▓рд┐рдЦрд╛ рдерд╛ рдХрд┐ рд╕реНрдкреНрд░рд┐рдВрдЧрд╕рд┐рдЯреА рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг "рд▓рдЧрднрдЧ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред" рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╣рд▓ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИред
SecurityRequestPostProcessors.java рд╡рд░реНрдЧ рдЗрд╕рдореЗрдВ рд╣рдорд╛рд░реА рдорджрдж рдХрд░реЗрдЧрд╛ред рдореИрдВ рдЗрд╕рдХреА рд╕рд╛рдордЧреНрд░реА рдкрд░ рдзреНрдпрд╛рди рдХреЗрдиреНрджреНрд░рд┐рдд рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛, рдмрд╕ рдЗрд╕реЗ
src/test/java
рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдХреЙрдкреА рдХрд░реЗрдВ рдФрд░ рдпрд╣ рджрд┐рдЦрд╛рдПрдВ рдХрд┐ рдпрд╣ рд╣рдорд╛рд░реА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдореЗрдВ рдХреИрд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╣рдо
setAuthentication(auth)
рдХреЛ рдХреЙрд▓ рдХреЛ рд╣рдЯрд╛ рджреЗрддреЗ рд╣реИрдВ рдЬреЛ рдмреЗрдХрд╛рд░ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдРрдб () рдкрджреНрдзрддрд┐ рдореЗрдВ рд╣рдо рдЕрдиреБрд░реЛрдз рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдПрдХ рдкрдВрдХреНрддрд┐ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ:
рдпрд╣реА рд╣реИ, рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рд╣рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ user1 рдХреА рдУрд░ рд╕реЗ рдЙрдирдХреЗ рд╕рднреА рдЕрдзрд┐рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдЕрдиреБрд░реЛрдз рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдФрд░ рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ! рд▓реЙрдЧ рдореЗрдВ, рд╣рдо рд╡рд╛рдВрдЫрд┐рдд
Granted Authorities: ROLE_USER
рджреЗрдЦрддреЗ рд╣реИрдВ
Granted Authorities: ROLE_USER
рд▓реЗрдХрд┐рди рдкреБрд░рд╛рдиреЗ рдкрд░реАрдХреНрд╖рдг рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд▓реНрджреА рдордд рдХрд░реЛ, рд╡реЗ рдЕрднреА рднреА рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдВрдЧреЗред рджрд░рдЕрд╕рд▓, рдЗрд╕ рд░реВрдк рдореЗрдВ рд╡реЗ рд╣рдорд╛рд░реЗ рд╕рд┐рд╕реНрдЯрдо рддрдХ рдЕрдирдзрд┐рдХреГрдд рдкрд╣реБрдВрдЪ рд╕реЗ рдЬреНрдпрд╛рджрд╛ рдХреБрдЫ рдирд╣реАрдВ рдкрд░рдЦ рд░рд╣реЗ рд╣реИрдВред рдФрд░ рдПрдХ рд╣реА рдШрд░ () рдФрд░ рд╕реВрдЪрдХрд╛рдВрдХ () рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдпреЗ рдпреВрдЖрд░рдПрд▓ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдкрд░ рдХреЛрдИ рдкреНрд░рддрд┐рдмрдВрдз рдирд╣реАрдВ рд▓рдЧрд╛рддреЗ рд╣реИрдВред рдФрд░ рд╡реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ!
рдЪрд▓рд┐рдП рд╡рд╛рдкрд╕ рдРрдб () рдореЗрдердб рдореЗрдВ рдЖрддреЗ рд╣реИрдВред рдЬрдм рд╣рдо рдЕрдирдзрд┐рдХреГрдд рд╣реЛрддреЗ рд╣реБрдП рд╕рдВрдкрд░реНрдХ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рд╣рдорд╛рд░рд╛ рдЖрд╡реЗрджрди рдХреНрдпрд╛ рдХрд░рддрд╛ рд╣реИ? рд╣рдореЗрдВ рд▓реЙрдЧрд┐рди рдкреГрд╖реНрда рджрд┐рдЦрд╛рддрд╛ рд╣реИ! рдПрдХ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ, рдЗрд╕рдХрд╛ рдорддрд▓рдм /login.jsp рдкрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рд╣реИ
рдЗрд╕рд▓рд┐рдП, рд╣рдо рдХрд┐рд╕реА рдЕрдиреНрдп рдХреЗ рд╕рд╛рде рд╕рдВрдкрд░реНрдХ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдирдзрд┐рдХреГрдд рдЕрдиреБрд░реЛрдз рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд╕рддреНрдпрд╛рдкрди рдХреА рдЬрдЧрд╣ рд▓реЗрддреЗ рд╣реИрдВ:
result.andExpect(MockMvcResultMatchers.redirectedUrl("http://localhost/login.jsp"))
рдЙрд╕реА рддрд░рд╣, рд╣рдЯрд╛рдиреЗ () рд╡рд┐рдзрд┐ рдХреЛ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ "рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ" рдХреА рдУрд░ рд╕реЗ, рд╣рдЯрд╛рдиреЗ рдХрд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдпрд╣ рд╕рд╣реА рд╣реИред
рдФрд░ рдпрд╣ рдПрдХ рдЕрдиреНрдп рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИ - рдЬрдм рдЕрдзрд┐рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ ROLE_USER рдПрдХ рд░рд┐рдХреЙрд░реНрдб рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЙрд╕реЗ рддреНрд░реБрдЯрд┐ 403, рдпрд╛ рдпреЛрдВ рдХрд╣реЗрдВ рдХрд┐ /error403.jsp рдкрд░ рдлрд╝реЙрд░рд╡рд░реНрдб рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рдкрд░рд┐рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдзрд┐ рдХрд╛ рд╢рд░реАрд░ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛ (рд╕рдВрдкрд░реНрдХ рдЖрдИрдбреА рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛, рдмрд╕ рд╕реЗрдЯ / 1):
mockMvc.perform(MockMvcRequestBuilders.get("/delete/1") .with(SecurityRequestPostProcessors.userDetailsService("user1"))) .andExpect(MockMvcResultMatchers.forwardedUrl("/error403.jsp"))
рд╡рд╣ рд╕рдм рд╣реИред рдирддреАрдЬрддрди, рд╣рдореЗрдВ 12 рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдзрд┐рдпрд╛рдВ рдорд┐рд▓реАрдВ, рдкреНрд░рддреНрдпреЗрдХ рдореЗрдВ 4 рдореЗрдВ рд╕реЗ 3 рдпреВрдЖрд░рдПрд▓ред рд╡реЗ рдЕрдирдзрд┐рдХреГрдд рдкрд╣реБрдВрдЪ, рдЕрдзрд┐рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдкрд╣реБрдВрдЪ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ ROLE_USER рдФрд░ ROLE_ADMINред рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдХреЗ рд╕рд╛рде, рд╣рдордиреЗ рд╕реЗрд╡рд╛рдУрдВ рдФрд░ рдбреАрдПрдУ рдХреЗ рддрд░реАрдХреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ред
GitHub рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реЛрд░реНрд╕ рдХреЛрдб