在单元测试具有构造函数和参数的类时,如何将自动有线依赖关系作为模拟传递给我们

时间:2019-06-14 05:14:17

标签: java groovy spock

我正在尝试对两个单独的类进行单元测试,一个类的构造函数是默认的构造函数,而另一个的构造函数具有一些参数。这两个类都有一个自动装配的组件,例如,

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)

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

对于如何正确执行此操作的任何帮助,我们将不胜感激

预先感谢

1 个答案:

答案 0 :(得分:1)

在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的显式构造函数创建对象,该类带有2个参数。然后,我们设置 someClass 字段(这看起来像是手动分配私有字段,但实际上我们是通过groovy中自动生成的setter对其进行设置的,您可以在此处了解有关隐式getter和setter的信息: http://groovy-lang.org/style-guide.html#_getters_and_setters)。