unit-testing - 我无法 mock 类(class)的属性(property)

标签 unit-testing mocking spock

我刚刚开始使用 spock,遇到一个问题..

    public class UserAuthentication {
        private UserDAO userDao;

        public boolean authenticateUser(String email, String password){
            User user = userDao.findUserByEmail(email);

            if(password.equals(user.getDecodedPassword())){
                return true;
            }
            return false;
        }
}


public interface UserDAO {

    User findUserByEmail(String login);

    void saveUser(User user);
}

public class User {

    private String email;
    private String decodedPassword;

    public User(String email, String decodedPassword) {
        this.email = email;
        this.decodedPassword = decodedPassword;
    }(...)

不幸的是我的测试抛出 NullPointerException:

import java.text.SimpleDateFormat
import spock.lang.Specification

class UserAuthenticationTest extends Specification {

    def "Authenticating correct user" () {
        setup:
        def email = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="37525a565e5b77525a565e5b1954585a" rel="noreferrer noopener nofollow">[email protected]</a>"
        def password = "qwerty1234"

        def userDao = Mock(UserDAO)
        userDao.findUserByEmail(email) >> new User(email, password)

        def userAuthenticator = new UserAuthentication()
        userAuthenticator.setUserDao(userDao)

        when:
        def result = userAuthenticator.authenticateUser(email, password)

        then:
        1 * userDao.findUserByEmail(email)
        result == true
    }

}

enter image description here

我得到了异常,因为调用时模拟不起作用(userDao.findUserByEmail(email); 在 UserAuthentication 类中)。

有人知道为什么吗?

最佳答案

当您模拟并验证返回的(从模拟)表达式时,应将其放置在 then block 下。 Here是文档和下面您可以找到更正的代码:

@Grab('org.spockframework:spock-core:0.7-groovy-2.0')
@Grab('cglib:cglib-nodep:3.1')

import spock.lang.*
import java.text.SimpleDateFormat

class UserAuthenticationTest extends Specification {

    def "Authenticating correct user" () {
        setup:
        def email = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6d08000c04012d08000c0401430e0200" rel="noreferrer noopener nofollow">[email protected]</a>"
        def password = "qwerty1234"

        def userDao = Mock(UserDAO) 

        def userAuthenticator = new UserAuthentication()
        userAuthenticator.userDao = userDao

        when:
        def result = userAuthenticator.authenticateUser(email, password)

        then:
        1 * userDao.findUserByEmail(email) >>  new User(email, password)
        result == true
    }
}

public class UserAuthentication {
    UserDAO userDao;

    public boolean authenticateUser(String email, String password){
        User user = userDao.findUserByEmail(email);        
        return password.equals(user.getDecodedPassword());
    }
}

public interface UserDAO {

    User findUserByEmail(String login);

    void saveUser(User user);
}

public class User {

    private String email;
    private String decodedPassword;

    public User(String email, String decodedPassword) {
        this.email = email;
        this.decodedPassword = decodedPassword;
    }

    public String getDecodedPassword() {
        return decodedPassword;
    }
}

关于unit-testing - 我无法 mock 类(class)的属性(property),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27878109/

相关文章:

unit-testing - 在 Golang 中进行单元测试时如何测试是否调用了 goroutine?

unit-testing - 如何配置vs2012只保留最新的测试结果?

java - 预期 Mockito 测试异常

spring - 如何将属性值注入(inject)到 Spock 测试中?

hibernate - Grails单元测试失败:此实现GORM当前不支持基于字符串的查询,例如[executeQuery]

grails - Jenkins 无法运行程序 "Xvfb": java. io.IOException:没有这样的文件或目录

javascript - QUnit knockout js 测试失败 : "ReferenceError: ViewModel is not defined"

unit-testing - Delphi - 测试事件是否分配给方法,但不覆盖每个委托(delegate)类型

javascript - 只为一个参数 stub 函数

java - 重新实现返回原始类型的方法