我正试图在没有运气的情况下将间谍注入到专用域private Map<Integer, IPatron> patrons;
中。该字段不属于任何构造函数,也不具有任何setter或getter。我正在尝试避免对源代码进行更改。
如果该字段设置为公开,我可以明确分配间谍,但据我了解,它应该自动发生。
package library;
import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import library.entities.IPatron;
import library.entities.Library;
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT) // allows unnecessary "stubbing"
class TestTing{
@Spy
private Map<Integer, IPatron> patrons;
@Spy
@InjectMocks
Library library;
@BeforeEach
void setUp(){
}
@Test
void getPatronList(){
library.getPatronList();
//someTest
patrons.size();
}
}
private Map<Integer, IPatron> patrons;
public Library() {
patrons = new HashMap<>();
}
@Override
public List<IPatron> getPatronList() {
return new ArrayList<IPatron>(patrons.values());
}
我的理解是@Spy private Map<Integer, IPatron> patrons;
将在被测类中找到private Map<Integer, IPatron> patrons;
并将其替换。
答案 0 :(得分:1)
首先,您正在正确测试类Library
,因此它不是间谍或其他任何东西,而只是常规实例,因此您应在测试中像这样创建它:
Library underTest = new Library(...);
现在,您的问题的答案不是关于Mockito,而是关于使代码可以进行单元测试。
没有任何产生的代码可以自动进行单元测试。
现在编写类Library
是不可能的(除非您用反射强行设置顾客)。反思也不是做到这一点的好方法。
我建议使用依赖注入原理并重构代码,如下所示:
class Library {
private Map<Integer, IPatron> patrons;
public Library(Map<Integer, IPatron> patrons) {
this.patrons = patrons;
}
}
然后在测试中,您可以将patrons
创建为地图,间谍,模拟或任何您想要模仿真实互动的内容,然后注入Library
:
Library underTest = new Library(patrons);
答案 1 :(得分:0)
您在Library类中硬性支持顾客依赖。不要使用硬编码。
我们应该要求依赖而不是自己定义。
我们在构造函数中要求强制性依赖,在setter中要求可选的依赖。
将构造函数的签名更改为以下内容:
public Library(Map<Integer, IPatron> patrons) {
this.patrons = patrons;
}
还可以让顾客最终确定。
在这种情况下,Library类并不关心创建顾客的方式及其内容。因为这不是它的责任。
您现在不需要任何间谍或嘲笑来测试Library类。而且它更具可扩展性和可测试性。