具有固定参数的“模拟”方法

时间:2018-03-07 12:35:03

标签: java junit mockito powermock powermockito

我的项目中有一个“Mailer”课程(当然会发送电子邮件)。对于测试,我希望Mailer#send(String toAddress)的每次通话都替换为Mailer#send("mail@example.com")

类似于:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassCallingMailer.class})
public class TestClass {

    @Test
    public void testMethod() {
        Mailer mailerMock = mock(Mailer.class);
        // this is where the magic happens; replace any toAddress with fixed email address
        when(mailerMock.send(any(String.class))).thenReturn(mailerMock.send("mail@example.com"));
        try {
            whenNew(Mailer.class).withAnyArguments().thenReturn(mailerMock);
        } catch (Exception e) {
            e.printStackTrace();
        }

        ClassCallingMailer someClass = new ClassCallingMailer();
        assertTrue(someClass.methodSendingMail());
    }
}

这段代码显然不起作用,但这可以通过某种方式实现吗? 也许这是一种完全错误的做法?

谢谢。

更新

我不确定这有多好但是它有效:

// ClassCallingMailer (no changes, just for completeness)
public class ClassCallingMailer {
    public boolean methodSendingMail() {
        Mailer mail = new Mailer();
        return mail.send(someEmailAddress);
    }
}

// TestMailer (new class)
public class TestMailer extends Mailer {
    // add all constructors from Mailer
    @Override
    public boolean send(String to) {
        return super.send("mail@example.com");
    }
}

// TestClass (with changes)
@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassCallingMailer.class})
public class TestClass {

    @Test
    public void testMethod() {
        // changed mock to spy and replaced Mailer with TestMailer
        Mailer mailerMock = spy(TestMailer.class);
        // removed "when(...).thenReturn(...)"
        try {
            whenNew(Mailer.class).withAnyArguments().thenReturn(mailerMock);
        } catch (Exception e) {
            e.printStackTrace();
        }

        ClassCallingMailer someClass = new ClassCallingMailer();
        assertTrue(someClass.methodSendingMail());
    }
}

1 个答案:

答案 0 :(得分:1)

如果你只想实现这种行为,我建议不要通过嘲笑来做。 您可以将Mailer课程扩展为一些TestMailer,其中您可以执行以下操作:

@Override
public void send(String toAddress){
  super.send("mail@example.com");
}

基本上,您覆盖Mailer的原始发送,并使用预定义的地址进行调用。

您可以在测试中使用这个新的子类。