Hi,  

I got a question here:


I got a project (spring mvc + shiro ),  the project is work perfect, but I’d 
like write some testing code for this project.  so I put spring-test framework 
into it.

here’s my code and how to put them together

first: the pom.xml

                <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-test</artifactId>
                        <type>jar</type>
                        <scope>test</scope>
                </dependency>

                <dependency>
                        <groupId>junit</groupId>
                        <artifactId>junit</artifactId>
                        <version>${junit.version}</version>
                        <scope>test</scope>
                </dependency>

                <dependency>
                        <groupId>org.hamcrest</groupId>
                        <artifactId>hamcrest-core</artifactId>
                        <version>${hamcrest.core.version}</version> 
                        <scope>test</scope> 
                </dependency>
                <dependency>
                        <groupId>org.mockito</groupId>
                        <artifactId>mockito-core</artifactId>
                        <version>${mockito.core.version}</version>
                        <scope>test</scope>
                </dependency>



and then I found some little code from google.  and make the testing 
configuration:


public abstract class AbstractShiroTest {
        

    protected static ThreadState subjectThreadState;

    public AbstractShiroTest() {
    }


    protected void setSubject(Subject subject) {
        clearSubject();
        subjectThreadState = createThreadState(subject);
        subjectThreadState.bind();
    }

    protected Subject getSubject() {
        return SecurityUtils.getSubject();
    }

    protected ThreadState createThreadState(Subject subject) {
        return new SubjectThreadState(subject);
    }

    /**
     * Clears Shiro's thread state, ensuring the thread remains clean for 
future test execution.
     */
    protected void clearSubject() {
        doClearSubject();
    }

    private static void doClearSubject() {
        if (subjectThreadState != null) {
            subjectThreadState.clear();
            subjectThreadState = null;
        }
    }

    protected static void 
setSecurityManager(org.apache.shiro.mgt.SecurityManager securityManager) {
        SecurityUtils.setSecurityManager(securityManager);
    }

    protected static org.apache.shiro.mgt.SecurityManager getSecurityManager() {
        return SecurityUtils.getSecurityManager();
    }

    @AfterClass
    public static void tearDownShiro() {
        doClearSubject();
        try {
                org.apache.shiro.mgt.SecurityManager securityManager = 
getSecurityManager();
            LifecycleUtils.destroy(securityManager);
        } catch (UnavailableSecurityManagerException e) {
            //we don't care about this when cleaning up the test environment
            //(for example, maybe the subclass is a unit test and it didn't
            // need a SecurityManager instance because it was using only 
            // mock Subject instances)
        }
        setSecurityManager(null);
    }

}






and then here’s the testing case class:


@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration(value="src/main/webapp")
@ContextHierarchy({
        @ContextConfiguration(name="root", classes=RootConfig.class),
        @ContextConfiguration(name="mvcconfig", classes=MvcConfig.class)
})

public class TestHomeController  extends AbstractShiroTest {




        
        @Before
        public void setUp() throws Exception {
                mvc = MockMvcBuilders.webAppContextSetup(wc).build();
                
                SecurityManager securityManager = mock(SecurityManager.class, 
RETURNS_DEEP_STUBS);
                ThreadContext.bind(securityManager);
                 
                testSubject = new 
Subject.Builder(getSecurityManager()).buildSubject();
                mockSession = new MockHttpSession(wc.getServletContext(), 
testSubject.getSession().getId().toString());
                setSubject(testSubject);
                
                UsernamePasswordToken token = new 
UsernamePasswordToken("admin", "123456");
                
                testSubject.login(token);
        
        
        }

        @After
        public void tearDown() throws Exception {
        }

        @Test
        public void testHome() throws Exception {
                mvc.perform(MockMvcRequestBuilders.get("/"))
                .andExpect(MockMvcResultMatchers.view().name("home"))
                
.andExpect(MockMvcResultMatchers.model().attributeExists("page"))
                
.andExpect(MockMvcResultMatchers.model().attributeExists("orders"))
                
.andExpect(MockMvcResultMatchers.model().attributeExists("totalPage"))
                .andReturn();
        
        
        }

        @Test
        public void testGetHome() {
                //fail("Not yet implemented");
        }

        @Test
        public void testArriveHome() {
                //fail("Not yet implemented");
        }

        
        @Autowired
        private WebApplicationContext wc;
        
        private MockMvc mvc;
        
        private Subject testSubject;
        
        private MockHttpSession mockSession;    
}


when I run this testing code, I found the testing case testHome is failed. 
because the except view is “home”, but in my controller logic, if the user’s 
role is not admin and sales, it will be get view “moms”.  so, here’s my 
question:  I already use the mock login in setUP: 
UsernamePasswordToken token = new UsernamePasswordToken("admin", "123456”);
testSubject.login(token);

but it is True, I didn’t find anywhere I can make a mock role for this subject. 
 just ask is there anyone can give me a little tips for how to make a mock Role 
for a subject?



@Brian, hi, Brian, would you help me a little tips?


Many thanks



Mike






Reply via email to