2016-03-07 36 views
4

我正在为我的Controller类在Spring.In中编写JUnit测试用例。我得到一个MissingMethodInvocationException说when()需要一个参数具有当调用when()。then方法中的WebTarget的模拟对象时,就成为'模拟调用方法'。当()需要一个参数必须是'一个模拟方法调用'

这是代码。

@Controller 
public class JobController { 

    WebTarget target = null; 
    ClientConfig config = new ClientConfig(); 
    Client client = ClientBuilder.newClient(config);` 
    List<ScheduleJob> scheduleJobsList = new ArrayList<ScheduleJob>(); 

    @RequestMapping(value = "displayScheduledJobs") 
    public ModelAndView displayScheduledJobs(@ModelAttribute(value = "Server") Server server) throws JAXBException { 

     List<Server> serverList = serverService.getJobServerList(user.getAccountId()); 
     target = client.target(getBaseURI(server)); 
     String xml = target.path("rest").path("getScheduledJobs").request().accept(MediaType.APPLICATION_XML).get(String.class); 
     if (xml.contains("<scheduleJob>") && xml.contains("</scheduleJob>")){ 
      //some code 
     } 
     model.addObject("scheduleJobsList", scheduleJobsList); 
     return model; 

    } 

    private static URI getBaseURI(Server server) { 
     if(server.getSecureFlag().equalsIgnoreCase("N")){ 
      return UriBuilder.fromUri("http://"+server.getServerIp()+":"+server.getServerPort()+"/jobserver").build(); 
     } else { 
      return UriBuilder.fromUri("https://"+server.getServerIp()+":"+server.getServerPort()+"/jobserver").build(); 
     } 
    } 
} 

这是我的测试代码。

@RunWith(MockitoJUnitRunner.class) 
public class JobControllerTest { 

    @Mock 
    private WebTarget target; 

    @Mock 
    private ClientConfig config; 

    @Mock 
    private Client client; 

    @Test 
    public void testdisplayScheduledJobs() throws JAXBException { 

     List<Server> serverList = new ArrayList<Server>(); 
     Server server = new Server(); 
     server.setSecureFlag("N"); 
     serverList.add(server); 
     config = new ClientConfig(); 
     client = ClientBuilder.newClient(config); 
     String xml = "<scheduledJobs>" + "</scheduledJobs>"; 

     when(serverService.getJobServerList(user.getAccountId())).thenReturn(serverList); 
     when(client.target(getBaseURI(server))).thenReturn(target); 


     when(target.path("rest")).thenReturn(target); //here the error is getting generated 
     when(target.path("getScheduledJobs")).thenReturn(target); 
     when(target.request()).thenReturn(builder); 
     when(builder.accept(MediaType.APPLICATION_XML)).thenReturn(builder); 
     when(builder.get(String.class)).thenReturn(xml); 

     model = jobController.displayScheduledJobs(server, request); 

     assertEquals("displayScheduledJobs", model.getViewName()); 

    } 
} 

请提出一个出路,这

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'. 
For example: 
    when(mock.getArticles()).thenReturn(articles); 

Also, this error might show up because: 
1. you stub either of: final/private/equals()/hashCode() methods. 
    Those methods *cannot* be stubbed/verified. 
2. inside when() you don't call method on mock but on some other object. 

at com.techm.job.administration.console.controller.JobControllerTest.testdisplayScheduledJobs(JobControllerTest.java:309) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:601) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
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:50) 
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 
+4

你上哪儿去定义'serverService'的模拟?此外,您不能这样做:'当(目标路径(“休息”)。路径(“getScheduledJobs”)。请求()。接受(MediaType.APPLICATION_XML).get(String.class))。然后返回(XML );'。 (target.path(“rest”))。thenReturn(target);','when(target.path(“getScheduledJobs”))。thenReturn(target);' ,'when(target.request())。thenReturn(...);'等等。 – user2004685

+0

你可以附加错误堆栈吗? – user2004685

+0

是的我忘了在代码中提到@Mock private ServerService serverService;我也尝试了你的建议,但没有运气! (target.path(“rest”))。thenReturn(target); (target.path(“getScheduledJobs”))。thenReturn(target); when(target.request())。thenReturn(builder); when(builder.accept(MediaType.APPLICATION_XML))。thenReturn(builder); when(builder.get(String.class))。thenReturn(xml); –

回答

4

你得到,因为在你的下面的一行代码的错误:

client = ClientBuilder.newClient(config); 

当你写这条语句,它取代您使用新客户端创建的客户端的模拟对象,因此client将不再被Mockito识别为模拟对象。

此外,我希望你正在创造builder的模拟,因为你在做when(builder.accept(MediaType.APPLICATION_XML)).thenReturn(builder);

另外,我看不到任何@InjectMocks声明。您必须创建您正在测试的类的对象,并使用@InjectMocks注释对其进行注释。

此外,您必须在testdisplayScheduledJobs()方法中执行MockitoAnnotations.initMocks(this);来初始化您的模拟。

下面是一个示例代码段,这将给你更多的见解:

public class Foo { 

    @Mock 
    private JerseyWebTarget target; 

    @Mock 
    private Builder requestBuilder; 

    @Mock 
    private Response serviceResponse; 

    @InjectMocks 
    private Foo foo = new Foo(); 

    @Rule 
    public ExpectedException thrown = ExpectedException.none(); 

    @Before 
    public void init() { 
     MockitoAnnotations.initMocks(this); 

     Mockito.when(target.queryParam(Matchers.anyString(), Matchers.anyString())) 
       .thenReturn(target); 

     Mockito.when(target.queryParam(Matchers.anyString(), Matchers.anyString())) 
       .thenReturn(target); 

     Mockito.when(target.queryParam(Matchers.anyString(), Matchers.anyString())) 
       .thenReturn(target); 

     Mockito.when(target.queryParam(Matchers.anyString(), Matchers.anyString())) 
       .thenReturn(target); 

     Mockito.when(target.request(MediaType.APPLICATION_JSON_TYPE)).thenReturn(
       requestBuilder); 
    } 

    @Test 
    public void testGetData() { 
     List<String> responseList = new ArrayList<>(); 
     responseList.add("foobar"); 

     Mockito.when(requestBuilder.get(Matchers.eq(Response.class))).thenReturn(serviceResponse); 

     Mockito.when(serviceResponse.getStatus()).thenReturn(200); 

     Mockito.when(serviceResponse.readEntity(Matchers.any(GenericType.class))).thenReturn(
       responseList); 

     List<String> resultList = foo.getData("foo", "bar"); 

     Mockito.verify(requestBuilder, Mockito.times(1)).get(Matchers.eq(Response.class)); 
     Mockito.verify(serviceResponse, Mockito.times(1)).getStatus(); 
     Mockito.verify(serviceResponse, Mockito.times(1)).readEntity(
       Matchers.any(GenericType.class)); 

     assertNotNull(resultList); 
     assertEquals(1, resultList.size()); 
     assertEquals("true", resultList.get(0).getConfigSetValue()); 
    } 
} 
相关问题