我不明白为什么test1()
会失败,尽管它与test2()
相同。另一种测试方法成功了......
我在assertTrue(str.equals("hello"));
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import junit.framework.TestCase;
class UnderTest {
private static UnderTest instance;
private ToMock toMock;
public void doSomething() {
String str = toMock.get();
assertTrue(str.equals("hello"));
}
public static UnderTest getInstance() {
if (instance == null) {
instance = new UnderTest();
}
return instance;
}
public void set(ToMock toMock) {
this.toMock = toMock;
}
public ToMock get() {
return toMock;
}
}
public class SomeTest extends TestCase {
private ToMock toMock;
private UnderTest underTest;
private String str;
public SomeTest() {
toMock = mock(ToMock.class);
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
str = (String) args[0];
return null;
}
}).when(toMock).set((String) org.mockito.Mockito.any());
when(toMock.get()).thenAnswer(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
return str;
}
});
UnderTest.getInstance().set(toMock);
}
@Before
public void setUp() throws Exception {
// UnderTest.getInstance().set(toMock);
}
@After
public void tearDown() throws Exception {
}
@Test
public void test1() {
toMock.set("hello");
UnderTest.getInstance().doSomething();
}
@Test
public void test2() {
toMock.set("hello");
UnderTest.getInstance().doSomething();
}
}
下面的界面应该放在一个额外的文件中。否则它不能被 Mockito 嘲笑。
public interface ToMock {
void set(String str);
String get();
}
但是一旦我取消注释:
@Before
public void setUp() throws Exception {
// UnderTest.getInstance().set(toMock);
}
这两种方法都会成功。我看不出这条指令如何影响str
字段。在str
和null
的调用之间看起来test1()
设置为test2()
。但为什么和在哪里?据我所知,我不必只是为了保持某些字段的当前值而调用setUp()
。在JUnit中的测试方法调用之间不应该丢失SomeTest
(包括str
)的状态。
如何解释?
答案 0 :(得分:4)
你正在混合JUnit 3和JUnit 4.不要。摆脱
extends TestCase {
这可能会让您的测试运行者使用JUnit 3来运行测试。
JUnit总是创建一个测试类的新实例来运行每个测试方法。
在JUnit 3中,运行器在执行任何方法之前准备所有实例。在你的情况下,执行基本上就像这样
SomeTest
,实例 A ToMock
,实例 B ,绑定到实例 A ,并在UnderTest
singleton SomeTest
,实例 C ToMock
,实例 D ,绑定到实例 C ,并在UnderTest
单例中注册,覆盖其中的内容前强> test1
set
实例 B ToMock
doSomething
实例D上调用ToMock
,因为这是存储在UnderTest
单例中的getInstance
,通过ToMock
set
实例 D 尚未调用SomeTest
。因此,相应的C
实例str
的{{1}}字段仍为null
。
使用JUnit 4,我们交替创建一个运行相应测试的实例。在您的测试用例中,UnderTest
单例不会与错误的ToMock
实例“混淆”。
答案 1 :(得分:1)
设置方法(@Before)和@After注释方法的任何更新都将在方法调用之间保持不变。
@Before
public void executedBeforeEach() {
....
}
每次调用test方法之前/之后都会调用该调用。如果这还不够,那么请考虑使用@BeforeClass注释。