我有一个简单的类,但带有匿名代码块。我需要用测试来覆盖这门课。
public class CleanerTask {
private final Logger log = LoggerFactory.getLogger(getClass());
DataWarehouseMessageDao dwMessageDao;
int cleanerDelay = 0;
TransactionTemplate template;
public CleanerTask(DataWarehouseMessageDao dwMessageDao, int cleanerDelay, TransactionTemplate template) {
this.dwMessageDao = dwMessageDao;
this.cleanerDelay = cleanerDelay;
this.template = template;
}
public void clean() {
log.info("Cleaner started");
final Date olderThan = new Date();
olderThan.setDate(olderThan.getDate() + cleanerDelay);
template.execute(new TransactionCallback<Date>() {
@Override
public Date doInTransaction(TransactionStatus transactionStatus) {
dwMessageDao.deleteAllByStatusAndDate(DataWarehouseMessageStatus.SAVED.getValue(), olderThan);
return olderThan;
}
});
}
}
和测试:
@RunWith(MockitoJUnitRunner.class)
public class CleanerTaskTest {
final static int CLEANER_DELAY = 5;
@Mock
DataWarehouseMessageDao dao;
@Mock
TransactionTemplate template;
CleanerTask cleanerTask;
@Before
public void setUp() throws Exception {
cleanerTask = new CleanerTask(dao, CLEANER_DELAY, template);
}
@Test
public void successfulScenario() {
try {
cleanerTask.clean();
verify(template, times(1)).execute(isA(TransactionCallback.class));
//that verify was not triggered
//verify(dao, times(1)).deleteAllByStatusAndDate(anyInt(), isA(Date.class));
} catch (Exception e) {
e.printStackTrace();
fail("No exceptions must occur");
}
}
}
注释行不工作。日志:需要但未调用:dao.DeleteAllByStatusAndDate(,isA(java.util.date));->在com.nxsystems.dw.publisher.handler.CleanerTaskTest.SuccessfulScenario(CleanerTaskTest.java:52)实际上,与这个模拟没有任何交互。
在com.nxsystems.dw.publisher.handler.CleanerTaskTest.SuccessfulScenario(CleanerTaskTest.Java:52)在Sun.Reflect.NativeMethodAccessorInvoke0(原生方法)在Sun.Reflect.NativeMethodAccessorInvoke(NativeMethodAccessorInvoke:39)在Sun.Reflect.DelegatingMethodAccessorInvoke(NativeMethodAccessorInvoke:25)在nit.runners.ParentRunner$1。Schedule(ParentRunner.Java:52)在org.junit.runners.ParentRunner.Runchildre(ParentRunner.Java:191)在org.junit.runners.ParentRunner.Access$000(ParentRunner.Java:42)在org.junit.runners.ParentRunner.Access$2.评估(ParentRunner.Java:184)在org.junit.runners.ParentRunner.Run(ParentRunner.Java:236)在
此外,当启动此tets时,调试器不会进入匿名块。那么如何让Mockito进入匿名块呢?
你不应该改变你的代码,这是对的。在单元测试中,您应该使用ArgumentCaptor捕获传递的参数,验证实例是TransactionCallback类型,并对其调用doInTransaction方法,而不是isA检查。这样您就可以验证是否使用预期的参数调用了dao(建议您可以使用eq匹配器来验证准确的值)。
这是真的,在这个测试中,你将同时测试两个东西,但这只是因为你的实现,我并不是说它是错误的。使用某些业务逻辑创建新实例总是会增加代码中的耦合,但这并不意味着我们不应该使用语言能力来实现这一点。
这里的问题是测试中的transactiontemplate
是一个模拟。因此,它具有与transactiontemplate
相同的接口,但它不知道如何操作。您负责它的实现--这就是模拟的全部意义。您在代码中显式调用template.execute()
,这就是第一次验证通过的原因。但是execute()
不是来自spring的那个(或者更准确地说,您测试中的template
不是spring的transactiontemplate
的实例,它只是它的一个模拟)--它是,好吧,让我们假设它是“空的”,因为它是在一个模拟上调用的,并且您没有告诉模拟在它上调用execute()
应该如何操作。
在这种情况下,我真的不鼓励您进行这样的单元测试,因为您在这里测试的是实现。你应该测试的,至少在我看来,是给定一定条件下的功能含义,当某件事发生时,就会出现某种结果。这将需要将其更改为集成测试(使用lets,比如DBUnit或其他任何东西),并断言是否实际删除了您应该删除的内容。我的意思是你真正关心的是什么--知道一些方法被调用了还是你希望的事情真的发生了?
但是,如果您真的想测试这段匿名代码,那么我只需要将它(整个匿名类)提取到一个单独的类中,并为这个新类编写一个单元测试,更确切地说是为它的doInTransaction()
方法编写单元测试。在这种情况下,您将使用new
创建它,在其中设置一个模拟的DatawarehouseMessageDAO
并简单地执行verify()
。
我正在使用Mockito编写一个JUnit测试用例,并得到一个NullPointerException。 在我的代码中是这样的:
我在我的Java,Spring Boot控制器中创建了一个函数,它允许我根据参数获得数据的和值,这很有效。然而,我很难理解用Junit和Mockito测试这个功能的最佳方式是什么?到目前为止,我已经创建了一个测试函数,它返回一个特定数组字段的值。如何能够返回。thenreturn()中的值,该值根据给定的serviceID求和?任何帮助或建议任何其他有用的帖子将被感谢,因为我无法找到任何相关的或我
我有这个过滤器类,在使用junit进行测试时需要尽可能高的代码覆盖率。 和测试等级: 当我运行时,它在 线 我如何避免这种情况? 我需要调用这个方法并执行里面的任何内容来提供所需的代码覆盖。
我应该如何测试异常?我可以mock connector并且我可以赋予它抛出异常的行为,但是我不明白下一步该怎么做。
问题内容: 我已经开始发现Mockito库,并且有一个我没有找到正确答案的问题。 例如,如果我的UserDAO类中有将用户保存到数据库中的此类方法: 我应该如何测试? 如果我想测试一个DAO类,那么我需要创建一个模拟,模拟,模拟等吗?如此不测试数据库本身? 但是,如果我还想测试dao和数据库的行为怎么办? 您能否提供一些代码示例,可能有用的链接,并显示实现此目的的最佳方法? 问题答案: 这是使用M
我对junit mockito非常陌生,并尝试使用mockito编写junit测试用例。 这是我的方法,我必须为此编写一个jUnit。 ChefService和ChefApi传递的方法参数来自第三方api 这里是呼叫chefService。listCookbookVersions()将返回CookBookVersion类类型的迭代器,如