@Test
    void notifyFailureAfterDoAuthenticateThrowsAuthenticationException() {
        AuthenticationListener mockListener = createMock(AuthenticationListener.class);
        AuthenticationToken token = newToken();

        final AuthenticationException ae = new AuthenticationException("dummy exception to test notification");

        abstractAuthenticator = new AbstractAuthenticator() {
            protected AuthenticationInfo doAuthenticate(AuthenticationToken token) throws AuthenticationException {
                throw ae;
            }
        };
        abstractAuthenticator.getAuthenticationListeners().add(mockListener);

        mockListener.onFailure(token, ae);
        replay(mockListener);

        boolean exceptionThrown = false;
        try {
            abstractAuthenticator.authenticate(token);
        } catch (AuthenticationException e) {
            exceptionThrown = true;
            assertEquals(e, ae);
        }
        verify(mockListener);

        if (!exceptionThrown) {
            fail("An AuthenticationException should have been thrown during the notifyFailure test case.");
        }
    }
Ensures a non-null <tt>Subject</tt> instance is returned from the authenticate() method after a valid
authentication attempt (i.e. the subclass's doAuthenticate implementation returns a valid, non-null
AuthenticationInfo object).
core/src/test/java/org/apache/shiro/authc/AbstractAuthenticatorTest.java