我是一个开发新手,尤其是单元测试新手。我想我的要求很简单,但我很想知道其他人对此的想法。
假设我有两个类,像这样-
public class First {
Second second ;
public First(){
second = new Second();
}
public String doSecond(){
return second.doSecond();
}
}
class Second {
public String doSecond(){
return "Do Something";
}
}
假设我正在编写单元测试来测试First.doSecond()
方法。然而,假设我想要这样模拟Second.doSecond()
类。我正在使用Mockito来做这件事。
public void testFirst(){
Second sec = mock(Second.class);
when(sec.doSecond()).thenReturn("Stubbed Second");
First first = new First();
assertEquals("Stubbed Second", first.doSecond());
}
我看到模仿没有生效,断言失败。没有办法模拟我想要测试的类的成员变量。?
发布于 2012-01-25 07:16:05
您需要提供一种访问成员变量的方法,以便可以传递一个mock (最常见的方法是setter方法或接受参数的构造函数)。
如果您的代码没有提供这样做的方法,那么它在TDD (测试驱动开发)中就被错误地分解了。
发布于 2013-07-04 23:58:30
如果你不能改变你的代码,这是不可能的。但是我喜欢依赖注入,并且Mockito支持它:
public class First {
@Resource
Second second;
public First() {
second = new Second();
}
public String doSecond() {
return second.doSecond();
}
}
你的测试:
@RunWith(MockitoJUnitRunner.class)
public class YourTest {
@Mock
Second second;
@InjectMocks
First first = new First();
public void testFirst(){
when(second.doSecond()).thenReturn("Stubbed Second");
assertEquals("Stubbed Second", first.doSecond());
}
}
这是非常好和容易的。
发布于 2012-01-25 07:06:27
如果仔细观察代码,您会发现测试中的second
属性仍然是Second
的实例,而不是模拟(在代码中不会将模拟传递给first
)。
最简单的方法是在First
类中为second
创建一个设置器,并显式地将模拟传递给它。
如下所示:
public class First {
Second second ;
public First(){
second = new Second();
}
public String doSecond(){
return second.doSecond();
}
public void setSecond(Second second) {
this.second = second;
}
}
class Second {
public String doSecond(){
return "Do Something";
}
}
....
public void testFirst(){
Second sec = mock(Second.class);
when(sec.doSecond()).thenReturn("Stubbed Second");
First first = new First();
first.setSecond(sec)
assertEquals("Stubbed Second", first.doSecond());
}
另一种方法是传递一个Second
实例作为First
的构造函数参数。
如果你不能修改代码,我想唯一的选择就是使用反射:
public void testFirst(){
Second sec = mock(Second.class);
when(sec.doSecond()).thenReturn("Stubbed Second");
First first = new First();
Field privateField = PrivateObject.class.
getDeclaredField("second");
privateField.setAccessible(true);
privateField.set(first, sec);
assertEquals("Stubbed Second", first.doSecond());
}
但你可能可以,因为很少在你不能控制的代码上进行测试(尽管可以想象这样一种场景,你必须测试一个外部库,因为它的作者没有:)
https://stackoverflow.com/questions/8995540
复制相似问题