java - 如何在单元测试具有带参数的构造函数的类时将 Autowiring 的依赖项作为模拟传递

标签 java groovy spock

我正在尝试对两个单独的类进行单元测试,其中一个类的构造函数是默认构造函数,另一个类的构造函数是具有一些参数的构造函数。这两个类都有一个 Autowiring 的组件,比如说,

class A {
  @Autowired
  private SomeClass someClass;
}
class B {
  @Autowired
  private SomeClass someClass;

  public B(int a, String b) {
    //method implementation
  }
}

我正在尝试对这两个类进行单元测试,如果我使用以下方法创建类对象,则对第一个类进行单元测试

def mockedSomeClass = Mock(SomeClass)
def a = new A(someClass:mockedSomeClass)

它工作正常。

但是对于第二个类,我尝试通过不同的语法传递构造函数参数和所需的依赖项

喜欢

def mockedSomeClass = Mock(SomeClass)
def b = new B(10, "g", someClass:mockedSomeClass)

def b = new B(someClass:mockedSomeClass, 10, "g")

def b = new B(10, "g")(someClass:mockedSomeClass)

所有这些都是反复试验,因为我找不到任何与此特定案例类似的文档。

任何有关如何正确执行此操作的帮助将不胜感激

提前致谢

最佳答案

在A类中,这样调用构造函数

new A(someClass:mockedSomeClass)

工作正常,因为在 groovy 中,隐式生成的默认构造函数支持通过 passing a named parameter 设置任何字段的值仅在默认构造函数中受支持。您有一个字段 (someClass) 已通过构造函数传递,这没问题。

但是,在 B 类中,您有一个带有两个参数的显式构造函数。请注意,您只能使用这些指定的两个参数(即 int a、String b)调用此构造函数,因为它是这样明确定义的。请记住,这不是类 A 中的默认构造函数,因此它不会自动支持通过传递命名参数来设置字段。

长话短说,要使其正常工作,您还必须明确指定第三个参数:

class B{

@Autowired
private SomeClass someClass;

public B(int a,String b, SomeClass someClass)
{
    //method implementation
    this.someClass = someClass;
}

然后你可以这样调用它:

def b=new B(10, "g", mockedSomeClass)

另一种方法:

上面的方法是我更喜欢的方法,因为它更简洁。原因是最好将所有强制依赖项都放在构造函数中以避免混淆。

但是,如果由于某些原因您无法更改Java源代码,您也可以通过这样创建对象来解决:

def b=new B(10, "g")
b.someClass = mockedSomeClass

在上面的例子中,我们首先通过调用 B 类的显式构造函数来创建对象,它有两个参数。然后我们设置 someClass 字段(这看起来像是手动分配私有(private)字段,但实际上我们是通过 groovy 中自动生成的 setter 来设置它,您可以在这里阅读隐式 getter 和 setter: http://groovy-lang.org/style-guide.html#_getters_and_setters ).

关于java - 如何在单元测试具有带参数的构造函数的类时将 Autowiring 的依赖项作为模拟传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56591743/

相关文章:

grails - 在 Intellij Idea : Bizarre error in Spock test: Cannot add Domain class [class x. y.Z] 中运行 grails 2.1.3 测试。它不是域

java - 用于 groovy 测试的 Maven 插件

java - 通过按下按钮将文本从 JTextfield 复制到剪贴板

java - 始终在顶部显示 TextView

grails - Groovy-等待 promise list

hibernate - 在单元测试中使用Java 8 Time API的Grails 3.1.1

gradle - Gradle和Spock很少需要运行测试

java - 在爬行超过一个页面时遇到逻辑问题,仅适用于第一页和第二页

java - 使用 Java 删除 CSS 注释

grails - g:formatDate与java.sql.Date类实例有关的问题