Why is my Spring Boot autowired JPA Repository failing JUnit test?

My JUnit test is failing with the following error: "java.lang.IllegalArgumentException: Could not find field [userRepository] of type [null] on target [com.clearsoft.demo.UserResource@756b2d90]"



Here is the Test class:



@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = App.class)
@WebAppConfiguration
@IntegrationTest
public class UserResourceTest {

@Autowired
private UserRepository userRepository;

private MockMvc restUserMockMvc;

@Before
public void setup() {
UserResource userResource = new UserResource();
ReflectionTestUtils.setField(userResource, "userRepository", userRepository);
this.restUserMockMvc = MockMvcBuilders.standaloneSetup(userResource).build();
}

@Test
public void testGetExistingUser() throws Exception {
restUserMockMvc.perform(get("/user/foo")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.id").value(1));
}
}


And here is the UserResource service:



@RestController
public class UserResource {

@Autowired
UserRepository repository;

@RequestMapping(value = "/user/{email}", method = RequestMethod.GET)
User hello(@PathVariable("email") String email) {
return repository.findByEmailAddressAllIgnoringCase(email);
}

}


Here is the repository:



public interface UserRepository extends Repository<User, Long> {

Page<User> findAll(Pageable pageable);

User findByEmailAddressAllIgnoringCase(String emailAddress);

}


And here is the Entity:



@Entity
@Table(name = "users")
public class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = -1680480089065575997L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;

@Basic(optional = false)
@NotNull
@Size(min = 1, max = 255)
@Column(name = "email_address")
@Pattern(regexp = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\."
+ "[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@"
+ "(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9]"
+ "(?:[a-z0-9-]*[a-z0-9])?", message = "{invalid.email}")
private String emailAddress;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getEmailAddress() {
return emailAddress;
}

public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}

}


Here is the App class:



@SpringBootApplication
public class App implements CommandLineRunner {

@Autowired
UserRepository repository;

public static void main(String[] args) {
SpringApplication.run(App.class);
}

@Override
public void run(String... strings) throws Exception {
System.out.println("**************** RUN RUN RUN RUN");
for (User user : repository.findAll(null)) {
System.out.println("****************" + user.getEmailAddress());
}
}
}


Answers

Exception comes from this line:





ReflectionTestUtils.setField(userResource, "userRepository", userRepository);


Second parameter of setField method is a field name. UserResource has field "repository" - not "userRepository" as you try to set in your test.





Bug in topological sort python implementation

I just wrote some code for doing a topological sort in Python, given a undirected graph.



G = {
7: [11, 8],
5: [11],
3: [8, 10],
11: [2, 9],
8: [9],
2: [],
9: [],
10: []
}

class GraphException(Exception):
def __init__(self, str):
pass

def has_incoming_edges(g, a_node):
"""
Return True if it has incoming edges,
False otherwise.
"""
for each_node in g:
if a_node in g[each_node]:
return True
return False

def remove_edge(g, start, end):
"""
Removes the edge start->end in g.
"""
edges = g[start]
edges.pop(edges.index(end))

def edges_exist(g):
for each_node in g:
if g[each_node]: return True
return False

def do_topsort(g):
S = [] # list of all nodes that have no incoming nodes
L = [] # topordering

for each_node in G:
if not has_incoming_edges(g, each_node):
S.append(each_node)

while S:
a_node = S.pop(0)
print "Popping", a_node
L.append(a_node)
x = g[a_node]
#TODO NEVER ITERATE ON A LIST AND REMOVE FROM IT AT
# THE SAME TIME
backup = g[a_node]
for each_connected in backup:
print ">>>", backup

print "Removing edge", a_node, each_connected
# Remove the edge from a_node to each_connected
remove_edge(g, a_node, each_connected)

print g

if not has_incoming_edges(g, each_connected):
print "Adding", each_connected
S.append(each_connected)

if edges_exist(g):
print g
print L
raise GraphException("Graph has cycles")
return L

def main():
global G
topsort = do_topsort(G)
print topsort

if __name__ == '__main__':
main()


The output I obtain from this code is as follows :-



Popping 3
>>> [8, 10]
Removing edge 3 8
{2: [], 3: [10], 5: [11], 7: [11, 8], 8: [9], 9: [], 10: [], 11: [2, 9]}
Popping 5
>>> [11]
Removing edge 5 11
{2: [], 3: [10], 5: [], 7: [11, 8], 8: [9], 9: [], 10: [], 11: [2, 9]}
Popping 7
>>> [11, 8]
Removing edge 7 11
{2: [], 3: [10], 5: [], 7: [8], 8: [9], 9: [], 10: [], 11: [2, 9]}
Adding 11
Popping 11
>>> [2, 9]
Removing edge 11 2
{2: [], 3: [10], 5: [], 7: [8], 8: [9], 9: [], 10: [], 11: [9]}
Adding 2
Popping 2
{2: [], 3: [10], 5: [], 7: [8], 8: [9], 9: [], 10: [], 11: [9]}
[3, 5, 7, 11, 2]
Traceback (most recent call last):
File "topsort.py", line 80, in <module>
main()
File "topsort.py", line 76, in main
topsort = do_topsort(G)
File "topsort.py", line 71, in do_topsort
raise GraphException("Graph has cycles")
__main__.GraphException


Notice that in the output there is a line Popping 7. It indicates that 7 is the node being processed in the for loop for each_connected in backup:. We can see that 7 is connected to both 11 and 8. However, the loop seems to be running only once and removing the edge 7-11. Node 8 does not seem to be processed. What am I doing wrong?



Answers

You are iterating over and removing elements from backup so you end up removing the wrong elements,use reversed:



for each_connected in reversed(backup):


Or copy the list:



for each_connected in backup[:]:


You can also remove the init method from your class:



class GraphException(Exception):
pass




Set language label programmatically

I have problems setting labels with language specifications programmatically after the component has been rendered. I have the following:



public class DateFilterWidget extends Div implements IdSpace {
private static final long serialVersionUID = 1L;

@Wire
Datebox startDate, endDate;

@Wire
Button filterButton;

@Wire
Label datefilterLabel;

String field;

public DateFilterWidget(String name, String filterField) {
Executions.createComponents("widgets/datefilter.zul", this, null);
Selectors.wireComponents(this, this, false);
Selectors.wireEventListeners(this, this);
datefilterLabel.setValue("${labels.data.dateFilterButton.label}");

this.field = filterField;
}
}


And the datefilter.zul



<hbox sclass="filterWidgetBox" align="center">
<label id="datefilterLabel" />
<datebox id="startDate" format="yyyy-MM-dd"
weekOfYear="true" width="105px"/>
<label value="-" />
<datebox id="endDate" format="yyyy-MM-dd"
weekOfYear="true" width="105px"/>
<button id="filterButtonc"
label="${labels.data.dateFilterButton.label}" />
</hbox>


I the above case the same label has been used for both the button and the label. The button language reference works fine, but the label that got a value programmatically don't work.



I know that I can use the Labels.getLabel("data.dateFilterButton.label"), but this solution removes the possibility to update language unless the whole application is rerendered with the new language.



Answers

label="${labels...}" is a static EL and will only get evaluated once the zul file is parsed, and has the same effect as calling setLabel(Labels.get(Labels.getLabel(...))).




The button language reference works fine




I don't really understand what you mean by that. When I run your example using Labels.getLabel(...) it works as expected, setting both labels in the current locale. When changing the locale during runtime e.g. from EN -> DE none of the labels update automatically, and both components need to be re-rendered and then update correctly.



To provide a solution, can you please give details on what you expect to happen? Or what you are trying to achieve regarding:




this solution removes the possibility to update language unless the whole application is re-rendered with the new language




"Update" can have several meanings, it's just not clear yet.



Robert



Answers

To set the value programmatically you should used the class Labels of the zk api.
You can see the javadoc clicking here:
Labels



And use the method getLabel.
Example:



datefilterLabel.setValue(Labels.getLabel("data.dateFilterButton.label");


If that is the right label key.





↑このページのトップヘ