Mockito 模拟无法正常工作

Jos*_*tar 0 java testing junit mocking mockito

我有以下测试方法:

@RunWith(MockitoJUnitRunner.class)
public class AccountManagerTest {

    @InjectMocks
    private AccountManager accountManager = new AccountManagerImpl(null);

    @Mock
    private AuthStorage authStorage;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    }

    /* REGISTER TESTS */

    @Test
    public void test_whenRegister_withAlreadyExistingEmail_thenDoNotRegister() throws AuthStorageException {
        String email = "foo@bar.com";
        String name = "Foo";
        String password = "123456";
        String password2 = "123456";

        doThrow(new AuthStorageException("Email already in use")).when(authStorage).registerNewUser(Matchers.any());
        assertFalse(accountManager.register(email, name, password, password2));
    }
}
Run Code Online (Sandbox Code Playgroud)

测试以下类方法:

@Override
    public Boolean register(String email, String name, String password, String password2) {
        if (password.equals(password2)) {
            try {
                String pwd = hashPassword(password);
                User user = new User(email, name, pwd);
                AuthStorage authStorage = new AuthStorageImpl();
                authStorage.registerNewUser(user);
                return true;
            } catch (NoSuchAlgorithmException | AuthStorageException e) {
                return false;
            }
        }
        // If passwords don't match
        return false;
    }
Run Code Online (Sandbox Code Playgroud)

据说,调用registerNewUser它时应该抛出异常,然后该方法将返回false,但是在调试时我看到异常没有抛出并且程序返回true。我究竟做错了什么?

Ser*_*man 5

首先,您不应该实例化插入模拟的对象:

@InjectMocks
private AccountManager accountManager = new AccountManagerImpl(null);
Run Code Online (Sandbox Code Playgroud)

相反,使用这个:

@InjectMocks
private AccountManager accountManager;
Run Code Online (Sandbox Code Playgroud)

那么如果你使用 Mockito 运行器:

@RunWith(MockitoJUnitRunner.class)
Run Code Online (Sandbox Code Playgroud)

你不应该直接注入模拟:

@Before
public void setup() {
    MockitoAnnotations.initMocks(this); //remove this line
}
Run Code Online (Sandbox Code Playgroud)

最后一点:你的模拟没有意义,因为你的注册方法中有一个局部变量:

AuthStorage authStorage = new AuthStorageImpl();
authStorage.registerNewUser(user);
Run Code Online (Sandbox Code Playgroud)

这使得该类使用您的模拟对象。