Alpha - 以 beta 为子级的父级
public class Alpha {
Beta beta;
public Alpha(int argument) {}
void start() {
beta = createBeta();
}
Beta createBeta() {
return new Beta(this);
}
}
贝塔 - 阿尔法的孩子,有查理
public class Beta {
Alpha alpha;
Charlie charlie;
public Beta(Alpha alpha) {
this.alpha = alpha;
this.charlie = createCharlie();
}
Charlie createCharlie() {
return new Charlie().shuffle();
}
}
查理 - 有一个列表,通常在生产中被洗牌
public class Charlie {
List<Integer> list = new ArrayList<Integer>();
public Charlie() {
for (int i = 0; i < 6; i++) {
list.add(i);
}
}
public Charlie shuffle() {
Collections.shuffle(list);
return this;
}
@Override
public String toString() {
return list.toString();
}
}
AlphaTest [需要此测试的帮助] - 想要尝试不同的洗牌变体,看看 alpha/beta 会如何反应。
public class AlphaTest {
Charlie special = new Charlie();
@Test
public void testSpecialCharlie() {
Alpha alpha = Mockito.spy(new Alpha(0));
Beta beta = Mockito.spy(alpha.createBeta());
Mockito.when(alpha.createBeta()).thenReturn(beta);
Mockito.when(beta.createCharlie()).thenReturn(special);
alpha.start();
// FAILURE: expected:<[0, 1, 2, 3, 4, 5]> but was:<[0, 4, 1, 5, 3, 2]>
assertEquals(special.list, alpha.beta.charlie.list);
}
}
目标是用查理的不同组合来测试Alpha/Beta。不确定最好的方法是什么?这是复制的确切代码。也愿意更改设置以方便测试。尝试了不同的变体,没有什么真正起作用的。非常感谢对此的帮助。
我不确定,我尝试了很多方法(模拟createCharlie()
功能,模拟Charlie
类,模拟shuffle()
,createCharlie()
移动到父类Alpha
,没有什么真正正常工作,或者我错过了一些东西。任何帮助将不胜感激。谢谢!
想知道为什么我不能这样做:
Charlie charlie = Mockito.mock(Charlie.class);
Mockito.when(charlie.shuffle()).thenReturn(special);
如果有人觉得这有用,我会在下面留下我的初步答案。
首先,在构造函数的最后一行放入Beta
:
System.out.println("Charlie created: " + this.charlie.hashCode());
运行测试后,您将看到查理被多次创建。
首先,当在测试中调用它时:
Beta beta = Mockito.spy(alpha.createBeta());
稍后当它被称为:
Mockito.when(alpha.createBeta()).thenReturn(beta);
所以 Beta 会一直引用真实的Charlie
,因为你嘲笑了createCharlie()
,当你调用你的代码时:
Assert.assertEquals(special.list, alpha.beta.charlie.list);
真正的Charlie
被称为,而不是嘲笑。你实现类的方式并不是很好,但是如果我只是回答你应该在测试中改变什么 - 你应该称之为:
Assert.assertEquals(special.list, alpha.beta.createCharlie().list);
在这种情况下,将调用模拟Charlie
,测试将通过。
以前的答案:
通常,当你对某些东西进行单元测试时,你的重点是单个测试类。您可以使用 @Spy
/@InjectMocks
.当你测试Beta
时,你应该嘲笑Charlie
,当你测试Alpha
时,你会嘲笑Beta
......
我不知道目的,但你的代码中的奇怪之处在于createCharlie()
和randomize()
返回Charlie
的实例。无论如何,你可以通过getter懒惰地创建Charlie
,如下所示:
public class Beta {
private Charlie charlie;
public Beta() {
}
public Charlie getCharlie() {
if (charlie == null) {
charlie = new Charlie();
}
return charlie;
}
public void doSomethingWithCharlie() {
getCharlie().randomize();
}
}
你可以在测试中像这样注射查理:
public class BetaTest{
@Mock(name="charlie") // variable name in Beta
private Charlie charlieMock;
@InjectMocks
private Beta beta;
@BeforeMethod
public void before() {
MockitoAnnotations.initMocks(this);
}
public void test1(){
beta.doSomethingWithCharlie();
}
}
另请参阅@InjectMocks文档。
(可选(您可以将包保护/公共方法添加到Alpha
:
Beta createBeta() {
return new Beta();
}
或
Beta getBeta() {
if(beta==null){
beta = new Beta();
}
return beta;
}
然后你可以注入Alpha
真实的Beta
返回模拟Charlie
:
公共类 AlphaTest { @Mock 查理查理莫克;
@Spy
Beta beta;
@Spy
Alpha alpha;
public void beforeTest() {
when(alpha.getBeta()).thenReturn(beta);
when(beta.getCharlie()).thenReturn(charlie);
}
}
另请参阅此内容。
感谢达里奥的回答,我将 Beta 类改为
public class Beta {
Alpha alpha;
Charlie _charlie;
public Beta(Alpha alpha) {
this.alpha = alpha;
this._charlie = getCharlie();
// PROBLEM: If I use this._charlie here, that will use the wrong charlie!
}
Charlie getCharlie() {
if (_charlie == null) {
_charlie = new Charlie().shuffle();
}
return _charlie;
}
}
然后,我从不访问查理alpha.beta._charlie,总是用getCharlie((,这应该可以解决我的问题。谢谢达里奥,非常感谢!