我使用java验证API来验证我的注释类:中的字段
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "note")
public class Note {
@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "date", columnDefinition = "DATE")
private LocalDate date;
@NotBlank(message = "Enter a topic")
@Column(name = "topic")
private String topic;
@NotBlank(message = "Content can't be empty")
@Column(name = "content")
private String content;
@Column(name = "type")
private NoteType noteType;
@NotNull
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
@JoinColumn(name = "user_id")
@JsonIgnore
private User user;
}
NoteService:
@Service
@AllArgsConstructor
public class NoteService {
@Autowired
private NoteRepository noteRepository;
@Autowired
private UserRepository userRepository;
public void addNote(@Valid Note note) {
note.setUser(getLoggedInUser());
if (validateNote(note)) {
noteRepository.save(note);
}
}
public List<Note> getNotes() {
return getLoggedInUser().getNotes();
}
public Note editNote(Note newNote, Long id) {
noteRepository.editNoteById(newNote, id);
return newNote;
}
public List<Note> getNotesByTopic(String topic) {
List<Note> notes = noteRepository.getNotesByTopicAndUser(topic, getLoggedInUser());
return notes;
}
public boolean validateNote(Note note) {
return validateNoteType(note.getNoteType())
&& note.getDate() != null;
}
public boolean validateNoteType(NoteType type) {
return type.equals(NoteType.NOTE)
|| type.equals(NoteType.SKILL);
}
public User getLoggedInUser() {
return userRepository.findByEmail(SecurityContextHolder.getContext().getAuthentication().getName());
}
}
测试:
@ExtendWith(MockitoExtension.class)
@ExtendWith(SpringExtension.class)
class NoteServiceTest {
@Mock
private NoteRepository noteRepositoryMock;
@Mock
private UserRepository userRepositoryMock;
@Mock
SecurityContext mockSecurityContext;
@Mock
Authentication authentication;
private NoteService noteService;
@BeforeEach
void setUp() {
noteService = new NoteService(noteRepositoryMock, userRepositoryMock);
Mockito.when(mockSecurityContext.getAuthentication()).thenReturn(authentication);
SecurityContextHolder.setContext(mockSecurityContext);
}
@Test
void shouldAddNote() {
LocalDate date = LocalDate.now();
Note note = new Note(0L, date, "test", "", NoteType.NOTE, null);
noteService.addNote(note);
Mockito.verify(noteRepositoryMock).save(note);
}
}
Note类中的字段用户用@NotNull进行了注释,我将一个null用户传递给这个注释,但注释仍在保存中。当我传递一个空字符串时也是一样。知道为什么会这样吗?我是单元测试的新手
I'm new to unit testing
-您的完全正确的问题与单元测试无关。@NotNull本身不执行任何操作。事实上,这是一份合同,内容如下:
数据成员(或任何其他用@NotNull注释的东西,如局部变量和参数(
不能为不应为null。
例如,而不是这样:
/**
* @param obj should not be null
*/
public void MyShinyMethod(Object obj)
{
// Some code goes here.
}
你可以这样写:
public void MyShinyMethod(@NotNull Object obj)
{
// Some code goes here.
}
p.S.
通常在编译时使用某种注释处理器,或者在运行时处理它的处理器是合适的。但我对注释处理并不是很了解。但我确信谷歌知道:-(
您需要使用@Validated注释激活服务类的验证,以便开始参数验证。
@Service
@AllArgsConstructor
@Validated
public class NoteService {
...
请参阅服务层中的Spring@Validated和SpringBoot:如何使用@Validated注释在JUnit中测试服务?了解更多详细信息。
如果出于某种原因,你需要手动执行验证,你总是可以这样做:
@Component
public class MyValidationImpl {
private final LocalValidatorFactoryBean validator;
public MyValidationImpl (LocalValidatorFactoryBean validator) {
this.validator = validator;
}
public void validate(Object o) {
Set<ConstraintViolation<Object>> set = validator.validate(o);
if (!set.isEmpty()) {
throw new IllegalArgumentException(
set.stream().map(x -> String.join(" ", x.getPropertyPath().toString(), x.getMessage())).collect(
Collectors.joining("nt")));
}
}
}
所以你的noteRepository是Mocked,所以你实际上并没有在你的存储库上调用save。
Mockito.verify(noteRepositoryMock).save(note);
您在这里要验证的只是调用了保存,而不是成功。