Java 测试在测试场景中不改变任何内容的void方法

Java 测试在测试场景中不改变任何内容的void方法,java,jakarta-ee,junit,mockito,Java,Jakarta Ee,Junit,Mockito,我知道每一个不起任何作用的方法都不应该被测试(甚至不存在)。问题是,我的方法通常会做一些事情,但对于测试场景,我必须模拟它所做的事情。但我仍然希望断言它将发送给外部对象的参数 听起来比实际情况更复杂-请查看我的代码片段以获得更好的理解: class A { @Inject private Mailer mailer; // Custom mailer class public void doSomething() { Date date = new Da

我知道每一个不起任何作用的方法都不应该被测试(甚至不存在)。问题是,我的方法通常会做一些事情,但对于测试场景,我必须模拟它所做的事情。但我仍然希望断言它将发送给外部对象的参数

听起来比实际情况更复杂-请查看我的代码片段以获得更好的理解:

class A {
    @Inject
    private Mailer mailer; // Custom mailer class

    public void doSomething() {
        Date date = new Date(); // dynamic parameter I do not care about in the test
        String parameter = "test"; // The parameter I want to test later

        mailer.sendMail(parameter, date);
    }
}

class ATest {
    @Mock
    @Produces
    private Mailer mailer;

    @Inject
    private A classToTest;

    @Test
    public void testDoSomething() throws Exception {

        classToTest.doSomething();

        assertThat(??).isEqualTo("test"); //How can I get the value of parameter?
    }
}
正如你所看到的,我需要模仿我的电子邮件发送者,这样我就不会每次测试运行时都发送电子邮件

参数
提升为全局变量是没有意义的


有没有办法在不更改
A
的代码的情况下测试
参数的值?如果不是的话,在不破坏我的类进行测试的情况下,什么是最好的解决方案?

您需要使用
Mockito。验证

verify(mailer, times(1)).sendMail("test");
Verify检查您的模拟发生了什么:一个方法被调用了多少次,以及为该方法提供了哪些参数


更新: 如果您想排除某些参数,可以使用
org.mockito.Matchers.any
——更容易将其作为静态导入。(注意:如果确实忽略了一些参数,那么现在要包含的参数必须包装在
org.mockito.Matchers.eq
)中


一种方法是使用可变对象参数化方法
doSomething
,您可以在方法执行时设置该对象,并在测试方法中断言该对象。否则,您还可以检查针对任何负面场景引发的异常,如

@Test(expected = EmailSendException.class)
public void testDoSomething(){
    ....
}

模拟您的邮件程序并测试mailer.sendMail(x)是否已被删除called@Stultuske我的邮件程序被模拟了,我需要
参数的值来测试。不仅仅是如果它被调用,还要检查它是否是用那个参数调用的。这就是我想要弄清楚的。这么说来,我还没找到这样的东西@StultuskeThanks感谢您的帮助,但实际上我有多个sendMail参数,其中一个参数是当前的
日期。如何验证
参数==“test”
,但忽略日期?我用一个例子更新了我的问题。这回答了我的问题。非常感谢。我会将其标记为已接受,但有一个小问题:您能做一些类似于
eqContains(“te”)
的事情吗?不过,我知道这一点后很快就发现了。它只是
Matchers.contains()
。您还可以查看
ArgumentCaptor
。假设您的参数是一个复杂的对象,有很多字段,而不是一个简单的字符串。您可以使用
ArgumentCaptor
捕获提供给模拟的对象,然后对其进行检查。这功能强大得多,但是对于像这样的简单检查来说,这太过分了。谢谢你的提示!这是一个可怕的计划。如果有其他原因导致抛出这样的异常,该怎么办?要知道他们在尝试测试一个快乐的流程,没有一个例外邮件程序会被嘲笑,所以它不会抛出任何东西。我可以手动抛出一些东西,但这仍然不允许我检查
参数的结果。
@Test(expected = EmailSendException.class)
public void testDoSomething(){
    ....
}