对象模拟不起作用(它的 null)和方法调用上的 returns NullPointerException
object mocking is not working (its null) and returns NullPointerException on method call
这里是我的class一个正在测试的-
class A extends ServerResource {
@Override
protected void doInit() throws ResourceException {
}
@Get
public String getUsers() {
String userJson = null;
// want to mock
UserFacade userFacade = new UserFacade();
// database call: want to return resources
List<Resource> resources = userFacade.getDrUsersByExample();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
userJson = gson.toJson(resources);
return userJson ;
}
}
这里是测试class -
@RunWith(MockitoJUnitRunner.class)
class ATest {
@Mock
UserFacade userFacade;
List<Resource> resources;
@Before
public void setUp() throws Exception {
Resource resource = new Resource();
resource.setName("user");
resource.setTask("manual");
resources.add(resource);
}
@Test
public void testUsers() {
when(userFacade.getDrUsersByExample()).thenReturn(resources);
A a = new A();
// causes NullPointerException for userFacade.getDrUsersByExample()
String userList = a.getUsers();
}
}
为什么即使在使用 when(userFacade.getDrUsersByExample()).thenReturn(resources)
之后,模拟对象仍会出现 NullPointerException?
Mocked UserFacade
需要显式注入到被测对象中。由于方法内部的 new UserFacade()
,A
目前与该依赖关系紧密耦合。
紧耦合被认为是代码异味和糟糕的设计。重构 class 以遵循显式依赖原则。
class A extends ServerResource {
UserFacade userFacade;
public A(UserFacade userFacade) {
this.userFacade = userFacade;
}
@Override
protected void doInit() throws ResourceException {
}
@Get
public String getUsers() {
String userJson = null;
// database call: want to return resources
List<Resource> resources = userFacade.getDrUsersByExample();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
userJson = gson.toJson(resources);
return userJson ;
}
}
然后需要更新测试才能完成。
@Test
public void testUsers() {
//Arrange
when(userFacade.getDrUsersByExample()).thenReturn(resources);
A a = new A(userFacade);
//Act
String userList = a.getUsers();
//Assert
//...
}
通过从@Nkosi 那里得到提示,我们需要以某种方式将模拟对象传递到正在测试的 class 中,我得到了对我有用的东西-
class A extends ServerResource {
UserFacade userFacade;
@Override
protected void doInit() throws ResourceException {
this.userFacade = userFacade;
}
@Get
public String getUsers() {
String userJson = null;
// database call: want to return resources
List<Resource> resources = userFacade.getDrUsersByExample();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
userJson = gson.toJson(resources);
return userJson ;
}
public void setUserFacade(UserFacade userFacade) {
this.userFacade= userFacade;
}
}
然后测试class-
@Test
public void testUsers() {
//Arrange
when(userFacade.getDrUsersByExample()).thenReturn(resources);
A a = new A();
a.setUserFacade(userFacade);
//Act
String userList = a.getUsers();
//Assert
//...
}
这里是我的class一个正在测试的-
class A extends ServerResource {
@Override
protected void doInit() throws ResourceException {
}
@Get
public String getUsers() {
String userJson = null;
// want to mock
UserFacade userFacade = new UserFacade();
// database call: want to return resources
List<Resource> resources = userFacade.getDrUsersByExample();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
userJson = gson.toJson(resources);
return userJson ;
}
}
这里是测试class -
@RunWith(MockitoJUnitRunner.class)
class ATest {
@Mock
UserFacade userFacade;
List<Resource> resources;
@Before
public void setUp() throws Exception {
Resource resource = new Resource();
resource.setName("user");
resource.setTask("manual");
resources.add(resource);
}
@Test
public void testUsers() {
when(userFacade.getDrUsersByExample()).thenReturn(resources);
A a = new A();
// causes NullPointerException for userFacade.getDrUsersByExample()
String userList = a.getUsers();
}
}
为什么即使在使用 when(userFacade.getDrUsersByExample()).thenReturn(resources)
之后,模拟对象仍会出现 NullPointerException?
Mocked UserFacade
需要显式注入到被测对象中。由于方法内部的 new UserFacade()
,A
目前与该依赖关系紧密耦合。
紧耦合被认为是代码异味和糟糕的设计。重构 class 以遵循显式依赖原则。
class A extends ServerResource {
UserFacade userFacade;
public A(UserFacade userFacade) {
this.userFacade = userFacade;
}
@Override
protected void doInit() throws ResourceException {
}
@Get
public String getUsers() {
String userJson = null;
// database call: want to return resources
List<Resource> resources = userFacade.getDrUsersByExample();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
userJson = gson.toJson(resources);
return userJson ;
}
}
然后需要更新测试才能完成。
@Test
public void testUsers() {
//Arrange
when(userFacade.getDrUsersByExample()).thenReturn(resources);
A a = new A(userFacade);
//Act
String userList = a.getUsers();
//Assert
//...
}
通过从@Nkosi 那里得到提示,我们需要以某种方式将模拟对象传递到正在测试的 class 中,我得到了对我有用的东西-
class A extends ServerResource {
UserFacade userFacade;
@Override
protected void doInit() throws ResourceException {
this.userFacade = userFacade;
}
@Get
public String getUsers() {
String userJson = null;
// database call: want to return resources
List<Resource> resources = userFacade.getDrUsersByExample();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
userJson = gson.toJson(resources);
return userJson ;
}
public void setUserFacade(UserFacade userFacade) {
this.userFacade= userFacade;
}
}
然后测试class-
@Test
public void testUsers() {
//Arrange
when(userFacade.getDrUsersByExample()).thenReturn(resources);
A a = new A();
a.setUserFacade(userFacade);
//Act
String userList = a.getUsers();
//Assert
//...
}