Java 嵌套在类中用于测试的模拟类
Alpha-父级,子级为betaJava 嵌套在类中用于测试的模拟类,java,unit-testing,testing,mocking,mockito,Java,Unit Testing,Testing,Mocking,Mockito,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 char
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();
}
}
Charlie-有一个列表,通常在制作中会被洗牌
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();
}
}
如果有人觉得这个有用,我会在下面留下我的初步答案 首先,在构造函数的最后一行中放入
Beta
:
System.out.println("Charlie created: " + this.charlie.hashCode());
运行测试后,您将看到charlie被创建了多次
首先,在测试中调用时:
Beta beta = Mockito.spy(alpha.createBeta());
后来,当这被称为:
Mockito.when(alpha.createBeta()).thenReturn(beta);
因此,Beta版保留了对realCharlie
的引用,并且因为您在调用代码时模拟了createCharlie()
:
Assert.assertEquals(special.list, alpha.beta.charlie.list);
真正的Charlie
被调用,而不是模拟的。您实现类的方式并不是很好,但如果我只回答您在测试中应该更改的内容,您应该称之为:
Assert.assertEquals(special.list, alpha.beta.createCharlie().list);
在这种情况下,将调用mockedCharlie
,测试将通过
先前的答复: 通常,当您进行单元测试时,您的注意力集中在单个测试类上。您可以使用
@Spy
/@injectmock
。当你测试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();
}
}
您可以像这样在测试中注入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();
}
}
另见文件
您可以选择将包保护/公共方法添加到Alpha
:
Beta createBeta() {
return new Beta();
}
或
然后你可以注入Alpha
realBeta
,返回mockedCharlie
:
公开课字母测验{
@嘲弄
查理·查理·莫克
@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。_charlie并且总是使用getCharlie(),这应该可以解决我的问题。谢谢你,达里奥,非常感谢 “什么都不能正常工作”是什么意思?对不起,我的意思是,我无法让它正常工作,我对测试非常陌生,所以我可能做得不对。我也可以稍微调整一下设置。请告诉我你会怎么做?谢谢使用JMockit对这样的代码进行单元测试非常容易(您只需声明一个
@Mocked Beta
或@Mocked Charlie
字段/参数,然后记录/验证任何调用,而不管实例是如何在CUT中创建的)。。。然而,我想问,为什么首先要嘲笑这里的一切?记住,嘲笑是不能滥用的。像Kent Beck(TDD的创始人)、Martin Fowler和其他“大师”这样的人不喜欢嘲弄(有充分的理由)。实际上我不知道什么是最好的方式。我没有设置JMockit。我认为这应该很简单,测试经验有限,但已经浪费了几天时间,仍然无法解决:(感谢Dario,也许我不清楚,我在问题中添加了更多信息。我同意测试单个类,但不幸的是,在这种情况下,Beta依赖于Alpha,我无法将它们解耦。目标是验证Alpha/Beta与不同charlie的交互,这就是为什么我想模拟charlie的创建,以便我可以再次编写测试st个不同的Charlie实例。希望能澄清一点?我还在回复中添加了其他信息。我尝试了第二种方法,但没有成功:(-我不确定我遗漏了什么,这也是我以前尝试过的。使用debug并验证Mock是否已注入Hi Dario,请再看一看问题。这是复制的精确代码,因此您确切知道我正在尝试做什么。非常感谢您为此花时间。非常期待您的下一次答复。添加了注释abo我真正需要的是设置我的代码,以便第一个getCharlie()调用返回特殊的
实例。
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;
}
}