@Mock 和 @InjectMocks 之间的差异

10 浏览
0 Comments

@Mock 和 @InjectMocks 之间的差异

Mockito框架中的@Mock@InjectMocks有何区别?

0
0 Comments

在测试类中,被测试的类应该使用@InjectMocks进行注解。这告诉Mockito需要将模拟对象注入到哪个类中:

private SomeManager someManager;

从此以后,我们可以指定类中的具体方法或对象,比如在这个例子中,SomeManager类中的SomeDependency对象将被替换为模拟对象:

private SomeDependency someDependency;

在这个例子中,SomeManager类中的SomeDependency对象将被模拟。

但是,如果someManager有多个构造函数,这样的方法还能正常工作吗?如果someManager有5个构造函数,它如何知道你想要使用哪一个?

当使用@InjectMocks注解时,Mockito会尝试使用默认构造函数来实例化被测试类的对象。如果被测试类有多个构造函数,且没有默认构造函数,那么就会抛出异常。为了解决这个问题,你可以在被测试类的构造函数上使用@Inject注解,以告诉Mockito使用哪个构造函数来实例化对象。例如,如果SomeManager类有5个构造函数,你可以使用以下代码来指定要使用的构造函数:

@InjectMocks
private SomeManager someManager;
@Inject
public SomeManager(SomeDependency someDependency) {
    this.someDependency = someDependency;
}

通过在构造函数上使用@Inject注解,你可以告诉Mockito使用带有SomeDependency参数的构造函数来实例化SomeManager对象。这样,Mockito就能正确地注入模拟对象。

0
0 Comments

@Mock和@InjectMocks之间的区别

在进行单元测试时,我们经常需要模拟对象或注入依赖项。Mockito是一个流行的Java框架,用于创建和管理模拟对象。在Mockito中,@Mock和@InjectMocks是两个常用的注解,用于创建和注入模拟对象。

在上面的示例代码中,我们有一个Game类和一个Player类。Game类依赖于Player类来执行attack方法。我们可以使用@Mock注解来模拟Player类,并使用when和thenReturn方法定义它的行为。最后,使用@InjectMocks注解将模拟的Player对象注入到Game类中。

Mockito在注入模拟对象时,会根据类的类型签名来匹配依赖项。因此,即使属性名不同,我们仍然可以使用@InjectMocks注解注入依赖项。

然而,有时候我们需要注入的依赖项本身也有依赖关系。例如,在上面的示例代码中,如果weapon实际上是一个类而不是一个字符串,该怎么办?

对于这种情况,我们可以使用@Spy注解来创建一个真实的对象,并使用@InjectMocks注解将其注入到需要的类中。这样,我们可以在创建依赖项时进行依赖注入。

总结起来,@Mock用于创建和管理模拟对象,@InjectMocks用于注入依赖项。通过使用这两个注解,我们可以更好地进行单元测试,并确保依赖项的正确注入。

注:该问题和解决方法摘自stackoverflow.com的评论。

0
0 Comments

@Mock和@InjectMocks之间的区别是什么?这个问题的出现是因为有人想知道这两个注解的作用和用法。下面是关于这个问题的一些讨论和解决方法。

首先,@Mock注解用于创建一个模拟对象,而@InjectMocks注解用于创建一个类的实例并将使用@Mock或@Spy注解创建的模拟对象注入到该实例中。

使用这两个注解时,需要使用(MockitoJUnitRunner.class)或Mockito.initMocks(this)来初始化这些模拟对象并注入它们(适用于JUnit 4)。而对于JUnit 5,需要使用(MockitoExtension.class)。

例如,在JUnit 4中的测试代码如下所示:

(MockitoJUnitRunner.class) // JUnit 4
public class SomeManagerTest {
    private SomeManager someManager;
    private SomeDependency someDependency; // this will be injected into someManager
    // tests...
}

这段代码中,SomeDependency对象将被注入到SomeManager实例中。

然而,注入模拟对象只适用于直接成员,不能递归注入。但是可以使用深度存根(deep stubs)来设置模拟对象以允许递归调用。

此外,Mockito.initMocks(this)方法已经被标记为弃用,应该使用Mockito.openMocks(this)方法来代替。

对于JUnit 5,如果测试类使用了@ExtendWith(MockitoExtension.class)注解,那么不需要使用(MockitoJUnitRunner.class)或Mockito.initMocks(this)来初始化模拟对象。

当然,还有一些其他的讨论和问题。例如,某些情况下无法通过注解提供一些无法由注解提供的项,如上下文。对于这种情况,可以通过其他方式来提供所需的项。

还有一位用户提到使用(MockitoExtension.class)时出现了异常。这可能是因为存在不必要的存根(UnnecessaryStubbingException)。可以通过删除不必要的存根或使用'lenient'严格度来解决这个问题。

@Mock和@InjectMocks是用于创建和注入模拟对象的注解。它们可以帮助我们在单元测试中模拟依赖对象,并将它们注入到被测试类的实例中。虽然它们在使用上有一些限制和注意事项,但它们是编写清晰和可维护的测试代码的有用工具。

0