代码之家  ›  专栏  ›  技术社区  ›  Alessandro Argentieri

Junit无法模拟类

  •  1
  • Alessandro Argentieri  · 技术社区  · 7 年前

    当我试图测试一个方法并用PowerMock和Mockito模拟其依赖关系时,我遇到了问题。我试图将依赖关系方法转换为非静态方法,并使用@Mock注释和@injectmock,但没有任何结果。

    以下是测试中的类和方法:

    /* class to be tested */
    public class LoginServiceImpl implements LoginService{
    
       /* method to be tested */
       @Override
       public String createJwt(String subject, String name, String permission, Date datenow)  throws java.io.UnsupportedEncodingException{
           Date expDate = datenow;
           expDate.setTime(datenow.getTime()+(300*1000));  //expiration time = 30 minutes
    
           String token = jwtUtils.generateJwt(subject, expDate, name, permission);
           return token;
       }
    }
    

    /* Dependency I cannot mock */
    public class JwtUtils {
    
        public static String generateJwt(String subject, Date date, String name, String scope) throws java.io.UnsupportedEncodingException{
            String jwt = Jwts.builder()
                .setSubject(subject)
                .setExpiration(date)
                .claim("name", name)
                .claim("scope", scope)
                .signWith(
                        SignatureAlgorithm.HS256,
                        "myPersonalSecretKey12345".getBytes("UTF-8")
                )
                .compact();
    
           return jwt;
       }
    }
    

    我不得不说,它甚至没有到达assert方法调用,但在when()时失败。然后返回结果()。 我还必须指定我尝试使用doReturn()和any()作为匹配器,但没有结果。

    @RunWith(MockitoJUnitRunner.class)          //to run Mockito
    @PrepareForTest({JwtUtils.class})           //powerMock annotations tomock classes containing static methods
    public class LoginServiceImplTest {
    
       @InjectMocks
       LoginServiceImpl loginService;          //System under test (SUT)
    
       @Test
       public void createJwtTest() throws Exception {
    
           SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd");
           Date expdate = ft.parse("2040-12-12");
           String jwt = JwtUtils.generateJwt("BDAGPP32E08F205K", expdate, "Pippo Baudo", "conduttore");
           //HERE IT'S WHERE IT FAILS:
           when(JwtUtils.generateJwt("BDAGPP32E08F205K", expdate, "Pippo Baudo", "conduttore")).thenReturn(jwt);
    
           assertThat(loginService.createJwt("BDAGPP32E08F205K", "Pippo Baudo", "conduttore", expdate), is(jwt));
       }
    }
    

    组织。莫基托。例外情况。误用。MissingMethodInvocationException:when()需要的参数必须是“模拟的方法调用”。 例如: when(mock.getArticles())。然后返回(物品);

    此外,出现此错误的原因可能是: 不能 被存根/验证。模拟方法 不支持在非公共父类上声明。

    在 通用域名格式。实例字节码。SpringBootJWT。服务。LoginServiceImplTest。createJwtTest1(loginserviceimpletest.java:114) 太阳反映NativeMethodAccessorImpl。调用(NativeMethodAccessorImpl.java:62) 太阳反映DelegatingMethodAccessorImpl。调用(DelegatingMethodAccessorImpl.java:43) 在java。郎。反思。方法调用(Method.java:498) 在 组织。朱尼特。内部的跑步者。模型可反射。运行(ReflectiveCallable.java:12) 在 在 组织。朱尼特。内部的跑步者。声明。调用方法。评估(InvokeMethod.java:17) 在org。朱尼特。跑步者。ParentRunner。runLeaf(ParentRunner.java:325)位于 组织。朱尼特。跑步者。BlockJUnit4ClassRunner。runChild(BlockJUnit4ClassRunner.java:78) 在 组织。朱尼特。跑步者。BlockJUnit4ClassRunner。runChild(BlockJUnit4ClassRunner.java:57) 组织。朱尼特。跑步者。ParentRunner 1美元。时间表(ParentRunner.java:71) 组织。朱尼特。跑步者。ParentRunner。运行(ParentRunner.java:363) 组织。莫基托。内部的跑步者。JUnit45和HigherRunneRimpl。run(JUnit45AndHigherRunnerImpl.java:37) 在 组织。莫基托。跑步者。MockitoJUnitRunner。运行(MockitoJUnitRunner.java:62) 在org。朱尼特。跑步者JUnitCore。运行(JUnitCore.java:137) 通用域名格式。intellij。junit4.JUnit4IdeaTestRunner。startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) 通用域名格式。intellij。rt.execution。朱尼特。IdeaTestRunner$中继器。startRunnerWithArgs(IdeaTestRunner.java:47) 在 通用域名格式。intellij。rt.execution。朱尼特。朱尼茨塔特。main(JUnitStarter.java:70)

    进程已完成,退出代码为255

    2 回复  |  直到 7 年前
        1
  •  3
  •   Marcin Krzyszkowski    7 年前

    尝试替换 @RunWith(MockitoJUnitRunner.class) @RunWith(PowerMockRunner.class) PowerMockRunner

        2
  •  1
  •   Timothy Truckle Vincent Boutot    7 年前

    没有这样的规则,方法在 static !

    PowerMock公司 你应该申请 控制反转 通过移除 方法中的关键字将该类的实例传递到单元中,最好使用 . 那样的话,你可以用普通的