使用@Asynchronous 方法对 SWF 进行单元测试
Unit testing SWF with @Asynchronous methods
我正在尝试测试具有异步方法的工作流 - 设置大致如下所示:
@RunWith(FlowBlockJUnit4ClassRunner.class)
public class testWorkflow {
@Rule
public WorkflowTest workflowTest = new WorkflowTest();
@Mock
protected Activities mockActivities;
@Before
public void setUp() throws Exception {
workflowTest.addActivitiesImplementation(mockActivities);
workflowTest.addWorkflowImplementationType(Workflow.class);
workflow = workflowFactory.getClient();
}
@Test
public void testMethod1Exception() throws Throwable {
doThrow(new RuntimeException("bang!"))
.when(mockActivities).method1();
try {
runWorkflow();
fail();
} catch (Exception e) {
verify(mockActivities, never()).method2();
}
}
private void runWorkflow() throws Throwable {
AsyncScope scope = new AsyncScope() {
@Override
protected void doAsync() {
workflow.run();
}
};
scope.eventLoop();
if (!scope.isComplete()) {
System.out.println(scope.getAsynchronousThreadDumpAsString());
}
}
}
我的问题出在我的代码中,工作流程大致如下所示:
public class Workflow {
public void run() {
final Promise<Result> pResult = client.method1();
doAsync(pResult);
}
@Asynchronous
public void doAsync(Promise<Result> pResult) {
...
}
}
我发现单元测试命中了 fail()
调用。读取 getAsynchronousThreadDumpAsString
方法的输出似乎表明工作流正在等待 pResult
可用于 @Asynchronous
方法,但它不可用,因为我抛出了异常。有没有办法让这样的测试起作用?我试图开始工作的实际测试是测试代码在 doCatch
块中的行为方式,但由于 @Asynchronous
方法调用,工作流程似乎冻结了。
我认为问题在于您同时使用了 AsyncScope 和 WorkflowTest 规则。 WorkflowTest 已经在 AsyncScope 中执行 @Test 方法,因此另一个 AsyncScope 可能会混淆它。
我会像这样重写您的代码:
@RunWith(FlowBlockJUnit4ClassRunner.class)
public class testWorkflow {
@Rule
public WorkflowTest workflowTest = new WorkflowTest();
@Mock
protected Activities mockActivities;
@Before
public void setUp() throws Exception {
workflowTest.addActivitiesImplementation(mockActivities);
workflowTest.addWorkflowImplementationType(Workflow.class);
workflow = workflowFactory.getClient();
}
@Test
public void testMethod1Exception() throws Throwable {
doThrow(new RuntimeException("bang!"))
.when(mockActivities).method1();
new TryCatchFinally() {
Throwable failure;
protected void doTry() {
workflow.run();
}
protected void doCatch(Throwable e) {
failure = e;
}
protected void doFinally() {
assertNotNull(failure);
}
};
}
}
但实际上,当使用 expected:
时,甚至以上所有内容都不是必需的
@RunWith(FlowBlockJUnit4ClassRunner.class)
public class testWorkflow {
@Rule
public WorkflowTest workflowTest = new WorkflowTest();
@Mock
protected Activities mockActivities;
@Before
public void setUp() throws Exception {
workflowTest.addActivitiesImplementation(mockActivities);
workflowTest.addWorkflowImplementationType(Workflow.class);
workflow = workflowFactory.getClient();
}
@Test(expected=RuntimeException.class)
public void testMethod1Exception() throws Throwable {
doThrow(new RuntimeException("bang!"))
.when(mockActivities).method1();
workflow.run();
}
}
@Test 方法中的代码在虚拟工作流的上下文中执行。这就是为什么,例如,内部测试工作流是使用普通客户端而不是外部客户端创建的。
我正在尝试测试具有异步方法的工作流 - 设置大致如下所示:
@RunWith(FlowBlockJUnit4ClassRunner.class)
public class testWorkflow {
@Rule
public WorkflowTest workflowTest = new WorkflowTest();
@Mock
protected Activities mockActivities;
@Before
public void setUp() throws Exception {
workflowTest.addActivitiesImplementation(mockActivities);
workflowTest.addWorkflowImplementationType(Workflow.class);
workflow = workflowFactory.getClient();
}
@Test
public void testMethod1Exception() throws Throwable {
doThrow(new RuntimeException("bang!"))
.when(mockActivities).method1();
try {
runWorkflow();
fail();
} catch (Exception e) {
verify(mockActivities, never()).method2();
}
}
private void runWorkflow() throws Throwable {
AsyncScope scope = new AsyncScope() {
@Override
protected void doAsync() {
workflow.run();
}
};
scope.eventLoop();
if (!scope.isComplete()) {
System.out.println(scope.getAsynchronousThreadDumpAsString());
}
}
}
我的问题出在我的代码中,工作流程大致如下所示:
public class Workflow {
public void run() {
final Promise<Result> pResult = client.method1();
doAsync(pResult);
}
@Asynchronous
public void doAsync(Promise<Result> pResult) {
...
}
}
我发现单元测试命中了 fail()
调用。读取 getAsynchronousThreadDumpAsString
方法的输出似乎表明工作流正在等待 pResult
可用于 @Asynchronous
方法,但它不可用,因为我抛出了异常。有没有办法让这样的测试起作用?我试图开始工作的实际测试是测试代码在 doCatch
块中的行为方式,但由于 @Asynchronous
方法调用,工作流程似乎冻结了。
我认为问题在于您同时使用了 AsyncScope 和 WorkflowTest 规则。 WorkflowTest 已经在 AsyncScope 中执行 @Test 方法,因此另一个 AsyncScope 可能会混淆它。 我会像这样重写您的代码:
@RunWith(FlowBlockJUnit4ClassRunner.class)
public class testWorkflow {
@Rule
public WorkflowTest workflowTest = new WorkflowTest();
@Mock
protected Activities mockActivities;
@Before
public void setUp() throws Exception {
workflowTest.addActivitiesImplementation(mockActivities);
workflowTest.addWorkflowImplementationType(Workflow.class);
workflow = workflowFactory.getClient();
}
@Test
public void testMethod1Exception() throws Throwable {
doThrow(new RuntimeException("bang!"))
.when(mockActivities).method1();
new TryCatchFinally() {
Throwable failure;
protected void doTry() {
workflow.run();
}
protected void doCatch(Throwable e) {
failure = e;
}
protected void doFinally() {
assertNotNull(failure);
}
};
}
}
但实际上,当使用 expected:
时,甚至以上所有内容都不是必需的@RunWith(FlowBlockJUnit4ClassRunner.class)
public class testWorkflow {
@Rule
public WorkflowTest workflowTest = new WorkflowTest();
@Mock
protected Activities mockActivities;
@Before
public void setUp() throws Exception {
workflowTest.addActivitiesImplementation(mockActivities);
workflowTest.addWorkflowImplementationType(Workflow.class);
workflow = workflowFactory.getClient();
}
@Test(expected=RuntimeException.class)
public void testMethod1Exception() throws Throwable {
doThrow(new RuntimeException("bang!"))
.when(mockActivities).method1();
workflow.run();
}
}
@Test 方法中的代码在虚拟工作流的上下文中执行。这就是为什么,例如,内部测试工作流是使用普通客户端而不是外部客户端创建的。