Reputation: 141
I have the following classes:
Store.java
@Controller
public class Store {
@Autowired
private List<Products> products;
@GetMapping(value = "cart/busket")
public String busket() {
return "redirect:/cart/index";
}
@GetMapping(value = "/")
public String index(final ModelMap model) {
model.addAttribute("products", this.products);
return "product/index";
}
@GetMapping(value = "cart/buy/{id}")
public String buy(@PathVariable("id") final String id, final HttpSession session) {
//some logic
return "redirect:/";
}
//and other methods
}
Main.java - which runs the application
@SpringBootApplication
@Configuration
@ImportResource("classpath*:beans.xml")
public class MainApp {
public static void main(final String[] args) {
SpringApplication.run(MainApp.class, args);
}
}
StoreTest.java - my class with tests
@SpringBootTest
@ContextConfiguration(classes = Store.class, locations = {"classpath*:beans.xml"})
@RunWith(SpringRunner.class)
public class StoreTest {
@InjectMocks
private Store myController;
private List<Products> products;
private MockMvc mockMvc;
@Before
public void setup() {
// Process mock annotations
MockitoAnnotations.initMocks(this);
// Setup Spring test in standalone mode
this.mockMvc = MockMvcBuilders.standaloneSetup(this.myController).build();
}
@Test
public void testBusket_StatusOK() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.get("/cart/busket"))
.andExpect(MockMvcResultMatchers.redirectedUrl("/cart/index"));
}
@Test
public void testBuy_StatusOK() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.get("cart/buy/1"))
.andExpect(MockMvcResultMatchers.redirectedUrl("/"));
}
@Test
public void testIndex_StatusOK() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.get("/"))
.andExpect(MockMvcResultMatchers.status().isOk());
}
}
My testBuy_StatusOK() doesn't work. It says: Redirected URL expected: "/" but was "null". I think this is because my dependencies are not implemented. I tried various ways, but it doesn’t work :\
Updated StoreTest.java
@WebMvcTest(Store.class)
@ContextConfiguration(classes = Store.class, locations = {"classpath*:beans.xml"})
@RunWith(SpringRunner.class)
public class StoreTest {
@MockBean
private List<Products> products;
@Autowired
private MockMvc mockMvc;
@Before
public void setup() {
// Process mock annotations
MockitoAnnotations.initMocks(this);
// Setup Spring test in standalone mode
this.mockMvc = MockMvcBuilders.standaloneSetup(this).build();
}
@Test
public void testBusket_StatusOK() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.get("/cart/busket"))
.andExpect(MockMvcResultMatchers.redirectedUrl("/cart/index"));
}
@Test
public void testBuy_StatusOK() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.get("cart/buy/1"))
.andExpect(MockMvcResultMatchers.redirectedUrl("/"));
}
@Test
public void testGetProducts_StatusOK() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.get("/"))
.andExpect(MockMvcResultMatchers.status().isOk());
}
@Test
public void testIndex_StatusOK() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.get("/"))
.andExpect(MockMvcResultMatchers.status().isOk());
}
}
Updated 2
Beans.xml - the file with beans
<beans>
...
<bean id="product1"
class="...entities.Products">
<constructor-arg name="name" value="Cherry" />
<constructor-arg name="description" value="This is very good cherry" />
<constructor-arg name="price" value="500" />
<constructor-arg name="id" value="1" />
</bean>
<bean id="product2"
class="...entities.Products">
<constructor-arg name="name" value="Cucumber" />
<constructor-arg name="description" value="This is an amazing cucumber" />
<constructor-arg name="price" value="1000" />
<constructor-arg name="id" value="2" />
</bean>
<bean id="product3"
class="...entities.Products">
<constructor-arg name="name" value="Apple" />
<constructor-arg name="description" value="This is pretty good apple" />
<constructor-arg name="price" value="3000" />
<constructor-arg name="id" value="3" />
</bean>
<util:list id="products" value-type="...entities.Products"> <ref bean="product1" /> <ref bean="product2" /> <ref bean="product3" /> </util:list>
</beans>
Upvotes: 0
Views: 1269
Reputation: 26084
The problem is that MockMvc is completely ignoring myController
variable from your test, and uses a controller it created.
To fix:
private Store myController;
from your test@MockBean
Also, if you intend to test only the web slice of your app
@SpringBootTest
to @WebMvcTest(Store.class)
@Autowired private MockMvc mockMvc;
Update
If you want to inject a @Bean when using @WebMvcTest you can provide it in your test:
@Configuration
class ProductConfig {
@Bean
public List<Product> getProducts() {
return List.of(new Product());
}
}
@WebMvcTest(value = Store.class)
@Import({ProductConfig.class})
public class StoreTest {
}
Update2
If you want to read beans from xml file, you can use:
@Configuration
@ImportResource({"classpath:beans.xml"})
class ProductConfig {
}
@WebMvcTest(value = Store.class)
@Import({ProductConfig.class})
public class StoreTest {
}
Upvotes: 2