【问题标题】:Why isn't passed into Mockito.when not used?为什么不传递给 Mockito.when 不使用?
【发布时间】:2019-09-12 19:08:12
【问题描述】:

我认为我对 when 的工作原理存在基本误解,或者更具体地说,Mockito 的工作原理存在误解。

我有一个服务类,它有一个通过构造函数注入的实用程序类。该实用程序类还有一些其他依赖项,由构造函数自动装配。

服务类方法调用实用程序类中的多个方法。该测试在调用的实用程序方法上使用 when/thenReturn 语句。当我对服务方法进行调用时,我会在使用 null 参数调用的实用程序方法上获得 NPE。但我希望设置 when 子句中的参数。代码如下:

@Service
public class ServiceClass {
    private Utility utility;
    public ServiceClass(Utility utility) {
        this.utility = utility;
    }

    public serviceMethod(MyDocument myDocument, List<Attachment> attachments) {
        SomeType variable1;
        OtherType variable2;
        List<String> stringList;
        long time;

        time = utility.method1(variable1, variable2);
        stringList = utility.method2(myDocument, attachments.get(0));
...
}

@Service
public class Utility {
    private Dependency1 depend1;
    private Dependency2 depend2;
    public Utility(Dependency1 depend1, Dependency2 depend2) {
        this.depend1 = depend1;
        this.depend2 = depend2;
    }

    public long method1(SomeType var1, OtherType var2) {
    ....
   }

   public List<String> method2(MyDocument myDoc, Attachment attach) {
   ....
   }

现在测试代码如下:

public TestClass {
    private ServiceClass serviceClass;

    @Mock
    private Depend1 depend1;

    @Mock 
    private Depend2 depend2;

    @InjectMocks
    private Utility utility;

    @Rule
    public MockitoRule rule = MockitoJUnit.rule();

    @Before
    public void setup() {
        serviceClass = new ServiceClass(utility);
    }

    @Test
    public testServiceMethod() {
        long time = System.currentTimeMillis();
        MyDocument doc = new MyDocument();
        List<Attachments> attachments = Arrays.asList(new Attachment(...), new Attachment(...));
        SomeType some = new SomeType();
        OtherType other = new OtherType();

        when(utility.method1(some, other)).thenReturn(time);
        when(utility.method2(doc, attachments.get(0)).thenReturn(Arrays.asList(new String("stg 1"), new String("stg 2"));

        String resp = serviceClass.serviceMethod(doc, attachments);
        assertEquals("service completed", resp);
    }
}

但是当 utility.method2 被调用时,myDocument 显示为 null。我期待它是 MyDocument 的一个实例。

我有什么配置错误吗?我在这里错过了一个概念吗?感谢所有帮助!

谢谢。

更新 更正了 serviceMethod 的参数。

【问题讨论】:

  • 你能用堆栈跟踪显示错误消息吗?
  • 您是否有理由模拟 Utility 的依赖项而不是直接模拟 Utility?
  • 这还能编译吗? ServiceClass.serviceMethod 在第一个参数中需要一个 MyDocument,但您在测试中将其传递给 SomeType。 ServiceClass.serviceMethod 上也没有返回类型。编译并运行您的示例并返回
  • when 不会向utility.method2 调用提供MyDocument 的实例。 MyDocument 实例是由调用者传入的,对吗?
  • @Deadpool 它只是一个调用utility.method2的Java NPE。 @kingkupps 我的印象是所有依赖项都必须是模拟的或真实的。 @MarkOfHall 是的,MyDocument 实例传入了。我没有意识到when 没有传入实例。

标签: java spring spring-boot mockito


【解决方案1】:

ServiceClass 是您正在测试的类,因此您应该在测试中仅使用 @Mock 注释该类的依赖项,在您的情况下为 utility 属性,删除 Depend1Depend1 声明。 setup 方法不是必需的,您可以在测试中使用 @InjectMocks 注释 serviceClass,它会自动处理注入。最后,您的TestClass 需要@RunWith(MockitoJunitRunner.class) 才能使一切正常,如果它不存在的话。

@RunWith(MockitoJunitRunner.class)
public class TestClass{
   @InjectMocks
   private ServiceClass serviceClass;

   @Mock
   private Utility utility;
} 

这是您的 TestClass 的基本定义,测试本身看起来是正确的,但可以改进为在“when”子句上使用ArgumentMatchers,并使用ArgumentCaptor 添加verify 子句以验证参数.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-04
    • 2012-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-09
    相关资源
    最近更新 更多