[英]How can I set up Zk Sessions (org.zkoss.zk.ui) so I can unit test a controller class extending GenericForwardComposer
I'm trying to unit test an existing ZK controller and I want to find a way to handle a call like the following while unit testing my Controller, 我正在尝试对现有的ZK控制器进行单元测试,并且想在对控制器进行单元测试时找到一种处理如下调用的方法,
Sessions.getCurrent().setAttribute("from", from.getValue());
I'd be happy to either replacing the offending code, or find a way around it for the unit test. 我很乐意替换有问题的代码,或者为单元测试找到解决方法。 My goal is testability by dealing with the
NullPointerException
我的目标是通过处理
NullPointerException
实现可测试性
My test is simple (it's not too bad a place to start...) 我的测试很简单(开始的地方还不错...)
@Test
public void zkControllerDoesMockingInitialisedSuccessfully() throws Exception {
T2TripBigDaoInterface tripBigDao = createMock(T2TripBigDao.class);
ZkFieldValidator fieldValidator = createMock(ZkTextFieldValidator.class);
FieldRangeValidator rangeValidator = createMock(DefaultFieldRangeValidator.class);
TripController controller = new TripController(tripBigDao, fieldValidator, rangeValidator);
replay(tripBigDao, fieldValidator, rangeValidator);
controller.onClick$getTrips(new Event("getTrips"));
verify(tripBigDao, fieldValidator, rangeValidator);
// Test purpose: Just get a unit test of the controller running to start with....
}
public class TripController extends GenericForwardComposer { .... public void onClick$getTrips(Event event) throws Exception { Sessions.getCurrent().setAttribute("from", from.getValue()); Sessions.getCurrent().setAttribute("to", to.getValue()); .... } ....
java.lang.NullPointerException at com.t2.webservice.controller.alert.TripController.onClick$getTrips(TripController.java:72) at com.t2.webservice.controller.alert.TripControllerTest.zkControllerDoesMockingInitialisedSuccessfully(TripControllerTest.java:45) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
This is one of the things I dislike most about ZK: their use of singletons and the impact that has on testability. 这是我最不喜欢ZK的事情之一:它们对单例的使用以及对可测试性的影响。
What I end up doing is removing any references to their singletons ( Sessions , Executions , Selectors ) from my controllers. 我最终要做的是从我的控制器中删除对它们的单例( Sessions , Executions , Selectors )的任何引用。 In normal operation these singletons get used, but in tests they can be mocked out.
在正常操作中,这些单例会被使用,但在测试中,它们可以被模拟。
How you go about this is up to you, I still haven't found a pattern I'm in love with. 如何处理取决于您,我仍然没有找到自己喜欢的模式。
Here's one idea.. 这是一个主意。
public class TripController extends GenericForwardComposer {
private final TripSessionManager tripSessionManager;
public TripController() {
// ZK calls the default constructor
this(new ZKTripSessionManager());
}
protected TripController(TripSessionManager tripSessionManager) {
this.tripSessionManager = tripSessionManager;
}
public void onClick$getTrips(Event event) throws Exception {
tripSessionManager.setTo(to.getValue());
tripSessionManager.setFrom(from.getValue());
}
}
Your TripSessionManager
would then look like this.. 然后,
TripSessionManager
将如下所示。
public interface TripSessionManager {
void setTo(String to);
void setFrom(String from);
}
With the default ZK implementation relying on the Sessions
singleton.. 默认的ZK实现依赖于
Sessions
单例。
public ZKTripSessionManager implements TripSessionManager {
public void setTo(String to) {
setAttribute("to", to);
}
public void setFrom(String from) {
setAttribute("from", from);
}
private void setAttribute(String name, String value) {
// only valid if called in a ZK managed thread
Sessions.getCurrent().setAttribute(name, value);
}
}
By abstracting out the implementation, you can test your controller with a mock TripSessionManager
.. 通过抽象化实现,可以使用模拟
TripSessionManager
..测试您的控制器。
@Test
public void test() {
TripSessionManager mockTripSessionManager = mock(TripSessionManager);
when(mockTripSessionManager.setTo(anyString()).thenAnswer(...);
when(mockTripSessionManager.setFrom(anyString()).thenAnswer(...);
TripController controller = new TripController(mockTripSessionManager);
}
You could also imagine different ways of managing these new dependencies (eg: avoid new ZKTripSessionManager()
) using dependency injection frameworks like Spring or Guice. 您还可以想象使用像Spring或Guice这样的依赖注入框架来管理这些新依赖的不同方法(例如:避免使用
new ZKTripSessionManager()
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.