<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 13. Testing 測試 # 13. Testing 測試 文檔的這一部分介紹了在單元測試中如何使用Shiro。 ## What to know for tests 由于我們已經涉及到了 [Subject](https://github.com/waylau/apache-shiro-1.2.x-reference/blob/master/IV.%20Auxiliary%20Support%20%E8%BE%85%E5%8A%A9%E6%94%AF%E6%8C%81/14.%20Custom%20Subjects%20%E8%87%AA%E5%AE%9A%E4%B9%89%20Subject.md) reference,我們知道 Subject 是“當前執行”用戶的特定安全視圖,且該 Subject 實例綁定到一個線程來確保我們知道在線程執行期間的任何時間是誰在執行邏輯。 這意味著三個基本的東西必須始終出現,為了能夠支持訪問當前正在執行的Subject: 1. 必須創建一個 Subject 實例 2. Subject 實例必須綁定當前執行的線程。 3. 在線程完成執行后(或如果該線程執行拋出異常),該 Subject 必須解除綁定來確保該線程在任何線程池環境中保持'clean'。 Shiro 擁有為正在運行的應用程序自動地執行 綁定/解除綁定 邏輯的構建。例如,在 Web 應用程序中,當過濾一個請求時,Shiro 的根過濾器執行該邏輯。但由于測試環境和框架不同,我們需要自己選擇自己的測試框架來執行此 綁定/解除綁定 邏輯。 ## Test Setup 設置 我們知道在創建一個 Subject 實例后,它必須被綁定線程。在該線程(或在這個例子中,是一個 test )完成執行后,我們必須解除 Subject 的綁定來保持線程的 'clean'. 幸運的是,現代測試框架如 JUnit 和 TestNG 已經能夠在本地支持'setup'和'teardown'的概念。我們可以利用這一支持來模擬 Shiro 在一個“完整的”應用程序中會做些什么。我們已經在下面創建了一個你能夠在你自己的測試中使用的抽象基類——隨意復制和修改如果你覺得合適的話。它能夠在單元測試和集成測試中使用(我在本例中使用 JUnit, 但 TestNG 也能夠工作得很好): ### AbstractShiroTest ``` import org.apache.shiro.SecurityUtils; import org.apache.shiro.UnavailableSecurityManagerException; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.support.SubjectThreadState; import org.apache.shiro.util.LifecycleUtils; import org.apache.shiro.util.ThreadState; import org.junit.AfterClass; /** * Abstract test case enabling Shiro in test environments. */ public abstract class AbstractShiroTest { private static ThreadState subjectThreadState; public AbstractShiroTest() { } /** * Allows subclasses to set the currently executing {@link Subject} instance. * * @param subject the Subject instance */ 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(SecurityManager securityManager) { SecurityUtils.setSecurityManager(securityManager); } protected static SecurityManager getSecurityManager() { return SecurityUtils.getSecurityManager(); } @AfterClass public static void tearDownShiro() { doClearSubject(); try { 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); } } ``` *Testing & Frameworks* *在AbstractShiroTest 類中的代碼使用 Shiro 的 ThreadState 概念及一個靜態的S ecurityManager。這些技術在測試和框架代碼中是很有用的,但幾乎不曾在應用程序代碼中使用。* *大多數使用 Shiro 工作的需要確保線程的一致性的終端用戶,幾乎總是使用 Shiro 的自動管理機制,即 Subject.associateWith 和Subject.execute 方法。這些方法包含在 [Subject thread association](http://shiro.apache.org/subject.html#Subject-ThreadAssociation) 參考文獻中。* ## Unit Testing 單元測試主要是測試你的代碼,且你的代碼是在有限的作用域內。當你考慮到 Shiro 時,你真正要關注的是你的代碼能夠與 Shiro 的API 正確的運行——你不會想做關于Shiro 的實現是否工作正常(這是 Shiro 開發團隊在Shiro 的代碼庫必須確保的東西)的必要測試。 測試 Shiro 的實現是否與你的實現協同工作是真實的集成測試(下面討論)。 ### ExampleShiroUnitTest 由于單元測試適用于測試你的邏輯(而不是你可能調用的任何實現),這對于模擬你邏輯所依賴的任何 API 來說是個很好的主意。這能夠與 Shiro 工作得很好——你可以模擬 Subject 實例,并使它反映任何情況下你所需的反應,這些反應是處于測試的代碼做出的。 但正如上文所述,在 Shiro 測試中關鍵是要記住在測試執行期間任何Subject 實例(模擬的或真實的)必須綁定到線程。因此,我們所需要做的是綁定模擬的 Subject 以確保如預期進行。 (這個例子使用 EasyMock,但 Mockito 也同樣地工作得很好): ``` import org.apache.shiro.subject.Subject; import org.junit.After; import org.junit.Test; import static org.easymock.EasyMock.*; /** * Simple example test class showing how one may perform unit tests for code that requires Shiro APIs. */ public class ExampleShiroUnitTest extends AbstractShiroTest { @Test public void testSimple() { //1. Create a mock authenticated Subject instance for the test to run: Subject subjectUnderTest = createNiceMock(Subject.class); expect(subjectUnderTest.isAuthenticated()).andReturn(true); //2. Bind the subject to the current thread: setSubject(subjectUnderTest); //perform test logic here. Any call to //SecurityUtils.getSubject() directly (or nested in the //call stack) will work properly. } @After public void tearDownSubject() { //3. Unbind the subject from the current thread: clearSubject(); } } ``` 正如你所看到的,我們沒有設立一個 Shiro SecurityManager 實例或配置一個Realm 或任何像這樣的東西。我們簡單地創建一個模擬Subject 實例,并通過調用setSubject 方法將它綁定到線程。這將確保任何在我們測試代碼中的調用或在代碼中我們正測試的SecurityUtils.getSubject()正常工作。 請注意,setSubject 方法實現將綁定你的模擬 Subject 到線程,且它仍將存在,直到你通過一個不同的 Subject 調用 setSubject 或直到你明確地通過調用 clearSubject() 將它從線程中清除。 保持 Subject 綁定到該線程多長時間(或在一個不同的測試中用來交換一個新的實例)取決于你及你的測試需求。 ### tearDownSubject() 在實例中的 tearDownSubject() 方法使用了 Junit 4 的注釋來確保該Subject 在每個測試方法執行后被清除,不管發生 什么。這要求你設立一個新的 Subject 實例并將它設置到每個需要執行的測試中。 然而這也不是絕對必要的。例如,你可以只每個測試開始時綁定一個新的Subject 實例(通過setSubject),也就是說,使用 @Before-annotated 方法。但如果你將要這么做,你可以同時使用 @After tearDownSubject() 方法來保持對稱及'clean'。 你可以手動地在每個方法中混合及匹配該 setup/teardown 邏輯或使用@Before 和 @After 注釋只要你認為合適。所有測試完成后,AbstractShiroTest 超類在無論怎樣都會將 Subject 從線程解除綁定,因為 @After 注釋在它的 tearDownShiro() 方法中。 ## Integration Testing 現在我們討論了單元測試的設置,讓我們討論一些關于集成測試的東西。集成測試是指測試跨API 邊界的實現。例如,測試當調用B 實現時A 實現是否工作,且B 實現是否做它該做的事情。你同樣也可以在Shiro 中輕松地執行集成測試。Shiro 的SecurityManager 實例及它所包含的東西(如 Realms 和 SessionManager 等)都是占用很少內存的非常輕量級的POJO。這意味著你可以為每一個你執行的測試類創建并銷毀一個SecurityManager 實例。當你的集成測試運行時,它們將使用“真實的” SecurityManager,且與你應用程序中相像的 Subject 實例將會在運行時使用。 ### ExampleShiroIntegrationTest 下面的實例代碼看起來與上面的單元測試實例幾乎相同,但這3 個步驟卻有些不同: 1. 現在有了step '0',它用來設立一個“真實的” SecurityManager 實例。 2. Step 1 現在通過Subject.Builder 構造一個“真實的” Subject 實例,并將它綁定到線程。 線程的綁定與解除綁定(step 2 和 3 )與單元測試實例中的作用一樣。 ``` import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; import org.junit.After; import org.junit.BeforeClass; import org.junit.Test; public class ExampleShiroIntegrationTest extends AbstractShiroTest { @BeforeClass public static void beforeClass() { //0. Build and set the SecurityManager used to build Subject instances used in your tests // This typically only needs to be done once per class if your shiro.ini doesn't change, // otherwise, you'll need to do this logic in each test that is different Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:test.shiro.ini"); setSecurityManager(factory.getInstance()); } @Test public void testSimple() { //1. Build the Subject instance for the test to run: Subject subjectUnderTest = new Subject.Builder(getSecurityManager()).buildSubject(); //2. Bind the subject to the current thread: setSubject(subjectUnderTest); //perform test logic here. Any call to //SecurityUtils.getSubject() directly (or nested in the //call stack) will work properly. } @AfterClass public void tearDownSubject() { //3. Unbind the subject from the current thread: clearSubject(); } } ``` 正如你所看到的,一個具體的 SecurityManager 實現被實例化,并通過setSecurityManager 方法使其余的測試能夠對其進行訪問。然后測試方法能夠使用該 SecurityManager,當使用 Subject.Builder 后通過調用getSecurityManager() 方法。 還要注意 SecurityManager 實例在 @BeforeClass 設置方法中只被設置一次——一個對于大多數測試類較為普遍的做法。如果你想,你可以創建一個新的 SecurityManager 實例并在任何時候從任何測試方法通過setSerurityManager 來設置它——例如,你可能會引用兩個不同的.ini 文件來構建一個根據你的測試需求而來的新 SecurityManager。 最后,與單元測試例子一樣,AbstractShiroTest 超類將會清除所有Shiro 產物(任何存在的 SecurityManager 及 Subject 實例)通過它的 @AfterClass tearDownShiro() 方法來確保該線程在下個測試類運行時是 'clean' 的。 ## 為文檔加把手 我們希望這篇文檔可以幫助你使用 Apache Shiro 進行工作,社區一直在不斷地完善和擴展文檔,如果你希望幫助 Shiro 項目,請在你認為需要的地方考慮更正、擴展或添加文檔,你提供的任何點滴幫助都將擴充社區并且提升 Shiro。 提供你的文檔的最簡單的途徑是將它發送到用戶[論壇](http://shiro-user.582556.n2.nabble.com/)或[郵件列表](http://shiro.apache.org/mailing-lists.html) *譯者注:*如果對本中文翻譯有疑議的或發現勘誤歡迎指正,[點此](https://github.com/waylau/apache-shiro-1.2.x-reference/issues)提問。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看