Closed jojoldu closed 7 years ago
@jojoldu Unfortunately, I can't tell what's happening from the information that you have provided. Can you please provide complete example that we can unzip or git clone that reproduces the problem you are seeing?
Thanks for the comment!
Share the Github link here github
I think it's because of @SpyBean
in HttpSession
.
HttpSession also uses the actual implementation that I do not implement, but what SpringBoot provides by default.
(Is there a reason similar to @SpyBean
not working in JpaRepository
?)
Thanks. The problem is that HttpSession
isn't registered as a bean. The Framework registers a SessionObjectFactory
by calling beanFactory.registerResolvableDependency
which is "intended for factory/context references that are supposed to be autowirable but are not defined as beans in the factory". Unfortunately, this means the spying on HttpSession
doesn't work as you'd like. There's no way for the @SpyBean
infrastructure to find and replace the HttpSession
bean is there isn't one. This causes it to create an HttpSession
bean which, along with the resolvable dependency defined by the Framework, causes the NoUniqueBeanDefinitionException
.
There isn't actually a need (that I can see) to use @SpyBean
in your test. This will work:
package com.jojoldu.springmockspybean.service;
import com.jojoldu.springmockspybean.domain.customer.Customer;
import com.jojoldu.springmockspybean.domain.order.CustomerOrder;
import com.jojoldu.springmockspybean.domain.order.CustomerOrderRepository;
import com.jojoldu.springmockspybean.domain.product.Product;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import javax.servlet.http.HttpSession;
import java.util.stream.Stream;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
/**
* Created by jojoldu@gmail.com on 2017. 9. 21.
* Blog : http://jojoldu.tistory.com
* Github : https://github.com/jojoldu
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class CustomerServiceSpyTest {
@Autowired
private CustomerService customerService;
@MockBean (name = "customerOrderRepository")
private CustomerOrderRepository customerOrderRepository;
@Autowired
private HttpSession httpSession;
@Test
public void saveMyOrderProductCountInSession () throws Exception {
// given
Customer customer = new Customer ();
httpSession.setAttribute("loginUser", customer);
CustomerOrder order = new CustomerOrder ();
order.addProduct (new Product ());
order.addProduct (new Product ());
given (customerOrderRepository.findAllByCustomer (customer))
.willReturn (Stream.of (order));
// when
customerService.saveMyOrderProductCountInSession ();
int count = (Integer) httpSession.getAttribute ("orderCount");
// then
assertThat (count, is (2));
}
}
We should consider adding a note to the documentation stating that the various dependencies registered by WebApplicationContextUtils
can't be spied.
Thanks for your kind answers and code
The code above is a sample code for an introduction to @MockBean
and @SpyBean
, so I wanted to clarify why!
Learn a lot Thanks again
Hi.
I'm using Spring Boot 1.5.7. I'm trying to use
@SpyBean
in@SpringBootTest
but I'm still getting aNoUniqueBeanDefinitionException
.@MockBean
is fine with@SpringBootTest
,@SpyBean
is happening Here's the code we tested: