【问题标题】:Expecting custom exception instead of null pointer exception while junit testing在junit测试时期望自定义异常而不是空指针异常
【发布时间】:2016-04-27 12:48:12
【问题描述】:

我在 java 类中有方法:

@Context
UriInfo uriInfo;
public void processRequest(@QueryParam ("userId") @DefaultValue("") String userId)
{
     String baseURI = uriInfo.getBaseUri().toString();
     if(userId == null)
     {
         //UserIdNotFoundException is my custom exception which extends Exceptition
         throw new UserIdNotFoundException();
     }
 }

当我在 junit 测试当 userId 参数为 Null 时期望 UserIdNotFoundException 的上述方法时,我收到以下断言错误:expected an instance of UserIdNotFoundException but <java.lang.NullPointerException> is java.lang.NullPointerException

@Test
public void testProcessRequest_throws_UserIdNotFoundException()
{
     expectedException.expect(UserIdNotFoundException.class);
     processRequest(null);
}

我的自定义异常类:

public class UserIdNotFoundException extends Exception
{

     public UserIdNotFoundException()
     {

     }

     public UserIdNotFoundException(String message)
     {
          super(message);
     }
}

【问题讨论】:

    标签: java unit-testing exception nullpointerexception mockito


    【解决方案1】:

    我更喜欢注释:

    @Test(expected = UserIdNotFoundException.class)
    public void testProcessRequest_throws_UserIdNotFoundException() {
         processRequest(null);
    }
    

    问题可能是您的processRequest 实现可能在您有机会检查用户ID 之前就命中了NPE。

    这是一件好事:您的测试表明实现不符合您的要求。你现在可以永远修复它。

    这就是 TDD 的优点。

    【讨论】:

    • 我的实现如何在检查之前遇到空指针异常。我没有在 userId 上调用任何字符串方法。或者我不明白你的意思。另外,我将 userId 作为 URL 中的查询参数。唯一的可能是它可能涉及一些空检查。
    • 您必须发布 processRequest 的实现,我才能为您详细说明。一个更好、更具教育意义的想法可能是在调试器中逐步完成该过程。在 processRequest 的第一行设置断点,看看观察到的行为与您的期望有何不符。
    • 我按照你的建议调试了它。该错误似乎显示在 uriInfo.getBaseUri().toString() 行上。所以我将该行放在 if 检查之后。测试现在显示绿色条。但我仍然没有得到原因。
    • 我还是不明白为什么在使用uriInfo时会碰到NPE
    • 你还没有发布实现,所以我帮不了你。你应该能够弄清楚这一点。
    【解决方案2】:

    您必须编写自定义异常类this example 可能会对您有所帮助。

    示例代码:

    class UserIdNotFoundException extends Exception{  
     UserIdNotFoundException  (String s){  
      super(s);  
     }  
    }  
    

    测试异常:

     public void processRequest(String userId)
    {
         if(userId == null)
         {
             //UserIdNotFoundException is my custom exception which extends Exception
             throw new UserIdNotFoundException("SOME MESSAGE");
         }
     } 
    

    从你的异常类中移除默认构造函数,JVM会为你隐式创建它/

    【讨论】:

    • 我已经编写了自定义异常类,但仍然遇到相同的断言错误。
    • 更新答案,试试看。
    • 去掉构造函数如何解决上述问题?
    • 我不是说它会解决问题,但它不是必需的。
    • 不是如何扩展异常的好例子。只有一个构造函数;我建议覆盖所有四个。
    【解决方案3】:

    您可能没有使用值设置uriInfo,并且您正在对空值调用方法。你确定你的测试设置为给 uriInfo 一个值吗?或者getBaseUri() 可能会返回null 并在其上调用toString() 可能会抛出NullPointerException。这可以通过在调试器中检查 getBaseUri() 的返回值来完成。

    通常,您可以使用带有 bean 的配置来运行测试,也可以添加 setter 来设置测试类中的值以模拟它或在测试中给出值。这应该有助于避免NullPointerException

    无论哪种方式,在对方法进行任何实际工作之前,您都应该始终进行失败验证。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-27
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多