gpt4 book ai didi

java - 如何从 StateMachineConfigurer 创建 StateMachine

转载 作者:搜寻专家 更新时间:2023-11-01 00:54:05 31 4
gpt4 key购买 nike

我有一个基于注释的状态机配置:

@Component @Scope(BeanDefinition.SCOPE_PROTOTYPE)
@EnableStateMachine(name = "machine1")
public class Machine1 extends
EnumStateMachineConfigurerAdapter<SimStates, SimEvents> {

@Override
public void configure(StateMachineStateConfigurer<SimStates, SimEvents> states) throws Exception {
states.withStates()
.initial(INIT)
.state(INIT)
.state(S1)
.state(FINISH)
.end(FINISH)
;
}
...

现在我想为它创建测试。我不希望隐式调用 getBean("machine1") "通过 StateMachineFactory.getStateMachine("machine1") ,这需要应用程序上下文。

我宁愿实例化Machine1并将其提供给某些构建器、配置器或适配器以获得 StateMachine<>实例。

public class Machine1Test {

@Test
public void testMachine1() throws Exception {

final StateMachineConfigurer<SimStates, SimEvents> smc =
new Machine1();


final StateMachineBuilder.Builder<SimStates, SimEvents> builder =
StateMachineBuilder.builder();

// can I use the builder together with smc? Or something else?

StateMachine<SimStates,SimEvents> sm = ... // how?
}
}

更新:我将“没有完整的应用程序上下文”更新为“没有对 getBean("machine1") 的隐式调用”。问题还在于了解 Spring 状态机的所有工厂、适配器、配置和配置器。

最佳答案

I'd rather instantiate Machine1 and feed it to some Builder, Configurator or Adapter to get a StateMachine<> instance.

Spring State Mahcine支持基于注释的实例化配置(例如通过 Adapter )或 Builder - 没有其他选择。

SM via Adapter

使用 @SpringBootTest(clasess = <YourEnumSMConfig> 绝对不会创建完整应用上下文:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = { Machine1.class})
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public class StateMachineTests {

@Autowired
private StateMachine<String, String> machine1;

@Test
public void testInitialState() throws Exception {
StatMachineTestPlan<SimState, SimEvent> plan = StateMachineTestPlanBuilder.<SimState, SimEvent>builder()
.defaultAwaitTime(2)
.stateMachine(machine1)
.step()
.expectStateChange(1)
.expectStateEntered(SimState.INITIAL)
.expectState(SimState.INITIAL)
.and()
.build()

plan.test();
}

}

Now I want to create Tests for it.

使用 TestPlanBuilder 进行测试:

有开箱即用的测试支持来测试 spring 状态机。它叫做 StateMachineTestPlan .您可以构建 StateMachineTestPlan使用 StateMachineTestPlanBuilder .

您可以通过声明以下依赖项来访问这些类:

<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-test</artifactId>
<version>2.0.3.RELEASE</version> // change version to match yours
<scope>test</scope>
</dependency>

有关测试的详细官方文档可用here .

SM via Builder

I would prefer not have an implicit call to getBean("machine1")" via StateMachineFactory.getStateMachine("machine1"), which would require an application context.

通过 Builder 创建 SM 不需要任何 Spring 上下文。

public class TestEventNotAccepted {

@Test
public void testEventNotAccepted() throws Exception {
StateMachine<String, String> machine = buildMachine();
StateMachineTestPlan<String, String> plan =
StateMachineTestPlanBuilder.<String, String>builder()
.defaultAwaitTime(2)
.stateMachine(machine)
.step()
.expectStates("SI")
.and()
.step()
.sendEvent("E2")
.and()
.build();
plan.test();
}

private StateMachine<String, String> buildMachine() throws Exception {
StateMachineBuilder.Builder<String, String> builder = StateMachineBuilder.builder();

builder.configureConfiguration()
.withConfiguration()
.taskExecutor(new SyncTaskExecutor())
.listener(customListener())
.autoStartup(true);

builder.configureStates()
.withStates()
.initial("SI")
.state("S1")
.state("S2");

builder.configureTransitions()
.withExternal()
.source("SI").target("S1")
.event("E1")
.action(c -> c.getExtendedState().getVariables().put("key1", "value1"))
.and()
.withExternal()
.source("S1").target("S2").event("E2");

return builder.build();
}

private StateMachineListener<String, String> customListener() {
return new StateMachineListenerAdapter<String, String>() {
@Override
public void eventNotAccepted(Message event) {
System.out.println("EVENT NOT ACCEPTED: " + event);
}
};
}

关于java - 如何从 StateMachineConfigurer 创建 StateMachine,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54828460/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com