2017-08-27 65 views
-2

我在我的服務下面的方法來嘲笑AWS SQS的Java與失敗的Mockito

@Override 
public Message recieveMessage(String queueUrl) { 
    Objects.requireNonNull(queueUrl); 
    ReceiveMessageRequest request = new ReceiveMessageRequest().withQueueUrl(queueUrl).withMaxNumberOfMessages(1); 
    ReceiveMessageResult receiveMessageResult = this.sqsClient.receiveMessage(request); 
    // As per the spec, we need to return only one message. 
    return receiveMessageResult.getMessages().get(0); 
} 

@Override 
public int getMessageCount(String queueUrl) { 
    GetQueueAttributesResult queueAttributes = sqsClient.getQueueAttributes(queueUrl, Arrays.asList("ApproximateNumberOfMessages")); 
    return Integer.valueOf(queueAttributes.getAttributes().get("ApproximateNumberOfMessages")); 
} 

和下面是我的測試情況下使用這些的Mockito方法與NPE失敗。

@Test 
public void testRecieveMessage() { 

    Message message = new Message(); 
    message.setBody("Message Body"); 

    List<Message> messages = new ArrayList<>(); 
    messages.add(message); 

    ReceiveMessageResult result = new ReceiveMessageResult(); 
    result.setMessages(messages); 

    when(mock(ReceiveMessageResult.class).getMessages()).thenReturn(messages); 
    when(mock(List.class).get(0)).thenReturn(message); 
    when(this.amazonSQSClient.receiveMessage(mock(ReceiveMessageRequest.class))).thenReturn(result); 

    this.amazonQueueService.recieveMessage(anyString()); 
    verify(this.amazonSQSClient, times(1)).receiveMessage(mock(ReceiveMessageRequest.class)); 
    //Assert.assertNotNull(msg); 
} 

在com.example.queue.service.impl.AmazonSQSService.recieveMessage(AmazonSQSService.java:46) 在com.example.AmazonSQSServiceTest.testRecieveMessage顯示java.lang.NullPointerException (AmazonSQSServiceTest.java:77) 在sun.reflect.NativeMethodAccessorImpl.invoke0(本機方法) 在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在java.lang中.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod $ 1.runReflective呼叫(FrameworkMethod.java:50) 在org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 在org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit。 runners.ParentRunner.runLeaf(ParentRunner.java:325) 在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner $ 1。 (org.junit.runners.java:58) at org.junit(ParentRunner.java:58) .runners.ParentRunner $ 2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java: 37) 在org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62) 在org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 在org.eclipse。 jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner .runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run (RemoteTestRunner.java:382) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

@Test 
public void testMessageCount() { 
    GetQueueAttributesResult result = new GetQueueAttributesResult(); 
    result.addAttributesEntry("ApproximateNumberOfMessages", "10"); 
    List<String> attrs = Arrays.asList("ApproximateNumberOfMessages"); 
    when(this.amazonSQSClient.getQueueAttributes(anyString(), eq(attrs))).thenReturn(result); 
    this.amazonQueueService.getMessageCount(anyString()); 
} 

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 無效使用參數匹配器! 2匹配器預期的,1記載: - 在com.example.AmazonSQSServiceTest.testMessageCount>(AmazonSQSServiceTest.java:96)

如果匹配器與原始值相結合可能會出現此例外: //不正確的: 的someMethod( anyObject(),「raw String」); 使用匹配器時,所有參數必須由匹配器提供。 例如: //正確: someMethod(anyObject(),eq(「String by matcher」));

欲瞭解更多信息,請參閱Matcher類的javadoc。

at com.example.queue.service.impl.AmazonSQSService.getMessageCount(AmazonSQSService.java:58) 
at com.example.AmazonSQSServiceTest.testMessageCount(AmazonSQSServiceTest.java:96) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37) 
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62) 
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 

我錯過了什麼嗎?

回答

2

這裏是你的代碼做什麼:

ReceiveMessageRequest request = new ReceiveMessageRequest().withQueueUrl(queueUrl).withMaxNumberOfMessages(1); 
ReceiveMessageResult receiveMessageResult = this.sqsClient.receiveMessage(request); 

所以它創建了一個新的請求,並傳遞給sqsClient.receiveMessage()部份新的要求。

這裏是你如何測試:

when(this.amazonSQSClient.receiveMessage(mock(ReceiveMessageRequest.class))).thenReturn(result); 

所以你的測試會告訴日模擬客戶端返回resultreceiveMessage()是帶一個模擬ReceiveMessageRequest。

這樣就無法工作。模擬ReceiveMessageRequest不等於代碼中使用的新請求。你需要做的是這樣

when(this.amazonSQSClient.receiveMessage(any(ReceiveMessageRequest.class))).thenReturn(result); 

這樣,whetever傳遞給receiveMessage的要求,模擬客戶端返回結果。

關於你提到的第二個問題:

this.amazonQueueService.getMessageCount(anyString()); 

沒有意義。你需要用一個真實的,給定的字符串來調用你的方法。