我正在使用SpringBoot 1.5.9并尝试进行集成测试。奇怪的是MongoRepository.save()方法在模拟MongoRepository上调用时更新对象。
我有一个反击类
public class Counter {
public String id;
public int seq;
public void increaseSeq() {
this.seq += 1;
}
}
他的存储库
public interface CounterRepository extends MongoRepository<Counter, String>{
Counter findById(String id);
List<Counter> findAll();
}
他的服务
@Service
public class CounterService {
@Autowired private CounterRepository counterRepository;
public Counter findCounter(String id) {
return counterRepository.findById(id);
}
public int getSeqAndIncrease(String id) {
Counter counter = findCounter(id);
if (counter == null) {
return -1;
}
counter.increaseSeq();
counterRepository.save(counter);
return counter.getSeq();
}
}
现在,当我进行系统集成并尝试模拟counterRepository时,它会发生一些我不期望的事情。 counterRepository.findById()返回一个Counter对象,其中&#39; seq&#39;场增加了。为什么? counterRepository.save()是否以任何方式影响结果(counterRepository被模拟,因此我认为save()不应该有任何影响)?
@RunWith(SpringRunner.class)
@SpringBootTest
public class FlowServiceTest {
@MockBean private CounterRepository counterRepository;
@Autowired private CounterService counterService;
@Before
public void setUp() {
Mockito.when(counterRepository.save(any(Counter.class))).then(arg -> arg.getArgumentAt(0, Counter.class));
Mockito.when(counterRepository.findById("flow")).thenReturn(new Counter("flow", 10));
}
@Test
public void testSavingInDatabase() {
System.out.println(counterRepository.findById("flow"));
counterService.getSeqAndIncreaseSafe("flow");
System.out.println(counterRepository.findById("flow"));
counterService.getSeqAndIncreaseSafe("flow");
System.out.println(counterRepository.findById("flow"));
}
}
它打印&#34; 10 11 12&#34;。为什么不打印&#39; 10 10 10&#39;?
答案 0 :(得分:0)
问题是这些行
counterRepository.save(counter);
return counter.getSeq();
你应该做的是这个
Counter saveCounter = counterRepository.save(counter);
return savedCounter.getSeq();
在getSeqAndIncrease方法中,您不返回已保存对象的序列 通过执行此操作,您将使保存的模拟语句无效。因为您没有使用mock返回的值。
答案 1 :(得分:0)
tl; dr - mock中返回的对象仅在mockito中初始化一次。所以我基本上每次都得到相同的引用,因为它是一个引用而不是一个新对象,所以值会更新。
完整答案:设置时
Mockito.when(counterRepository.findById("flow")).thenReturn(new Counter("flow", 10));
,每次返回一个新对象似乎都很直观,但返回对象在测试开始时只初始化一次,并在所有后续调用时返回。
然后,在我的代码中我做
counter.increaseSeq();
增加了&#39; seq&#39;找到的对象(此对象来自Mockito)。然后在下一次调用时,Mockito返回第一个初始化的对象,该对象在此期间更新; Mockito并没有像它看起来那样返回一个新对象。