Java 为什么测试中不同模拟会话的会话范围bean相同
我试图在SpringBoot中测试会话范围的bean,但遇到了问题。 我已经创建了两个MockHttpSession,并尝试将它们注入到控制器方法中,然后将其添加到作用域bean中。如果我运行应用程序,这些bean在每个作用域中都是不同的,但当我尝试测试它时,对象是相同的。这是我的测试:Java 为什么测试中不同模拟会话的会话范围bean相同,java,spring,session,testing,spring-boot,Java,Spring,Session,Testing,Spring Boot,我试图在SpringBoot中测试会话范围的bean,但遇到了问题。 我已经创建了两个MockHttpSession,并尝试将它们注入到控制器方法中,然后将其添加到作用域bean中。如果我运行应用程序,这些bean在每个作用域中都是不同的,但当我尝试测试它时,对象是相同的。这是我的测试: @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest public class ObserverSessionScopedIT { @Autowire
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class ObserverSessionScopedIT {
@Autowired
private
ObserverController controller;
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Test
public void sessionScope() throws Exception {
MockHttpSession sessionFirst = new MockHttpSession();
MockHttpSession sessionSecond = new MockHttpSession();
sessionFirst.changeSessionId();
sessionSecond.changeSessionId();
controller.startObserving(temporaryFolder.getRoot().getAbsolutePath(), sessionFirst);
controller.startObserving(temporaryFolder.getRoot().getAbsolutePath(), sessionSecond);
Subscriptions subscriptionsFirst = (Subscriptions) sessionFirst.getAttribute("Subscriptions");
Subscriptions subscriptionsSecond = (Subscriptions) sessionSecond.getAttribute("Subscriptions");
Assertions.assertThat(subscriptionsFirst).isNotSameAs(subscriptionsSecond);
}
以下是我在控制器中的操作方式:
private static final String SUBSCRIPTION = "Subscriptions";
(...)
@Autowired
private Subscriptions subscriptions;
@CrossOrigin
@RequestMapping(path = "/start", method = RequestMethod.POST)
@ResponseBody ResponseEntity<String> startObserving(@RequestBody String path, HttpSession httpSession) throws IOException {
(...)
httpSession.setAttribute(SUBSCRIPTION, subscriptions);
(...)
}
为什么应用程序运行时我有两个不同的对象,但在测试中它是相同的引用?我认为它可能连接到测试中的上下文,但我可以使用主应用程序上下文运行测试吗?它实际上可以正常工作。。。您将获得一个代理,该代理反过来委托给不同的(实际范围内的)对象。你基本上是在比较代理,它们总是一样的。但为什么我在实际应用中使用控制器中的getAttribute(“订阅”)时,每个会话的对象都不同呢?它不是。。。它是一个代理。。。代理最终委托给实际对象。可能是由于序列化/反序列化,哈希不同,但它仍然是一个代理,而不是实际的会话作用域对象。。。检查您的所有属性,您将看到还有另一个属性(而且您不应该首先将其存储在会话中,因为它已经是会话范围的)。您考虑“scopedTarget.”属性吗?但在这种情况下,订阅是否可以是代理,而scopedTarget是否可以是实际的会话对象?也许你们可以给我指一个我可以在春天读到代理的地方?我想我没有足够的知识来完全理解这个主题,这基本上就是我在最后两条评论中试图解释的。。。如果您想知道作用域是如何工作的,请检查
SessionScope
的源代码,看看其中发生了什么,以及ScopedProxyCreator
是如何工作的。它实际上是按照它应该工作的方式工作的。。。您将获得一个代理,该代理反过来委托给不同的(实际范围内的)对象。你基本上是在比较代理,它们总是一样的。但为什么我在实际应用中使用控制器中的getAttribute(“订阅”)时,每个会话的对象都不同呢?它不是。。。它是一个代理。。。代理最终委托给实际对象。可能是由于序列化/反序列化,哈希不同,但它仍然是一个代理,而不是实际的会话作用域对象。。。检查您的所有属性,您将看到还有另一个属性(而且您不应该首先将其存储在会话中,因为它已经是会话范围的)。您考虑“scopedTarget.”属性吗?但在这种情况下,订阅是否可以是代理,而scopedTarget是否可以是实际的会话对象?也许你们可以给我指一个我可以在春天读到代理的地方?我想我没有足够的知识来完全理解这个主题,这基本上就是我在最后两条评论中试图解释的。。。如果您想知道作用域是如何工作的,请检查SessionScope
的源代码,看看其中发生了什么,以及ScopedProxyCreator
是如何工作的。
@Service
@SessionScope
public class Subscriptions implements AutoCloseable{