单元测试(模拟)数据库,如何通过模拟验证数据库方法? [英] Unit Testing(Mocking) Databases, How To Verify Database Methods With Mocking?

查看:509
本文介绍了单元测试(模拟)数据库,如何通过模拟验证数据库方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于一个人以前没有进行单元测试和模拟的经验,所以我跟随Mockito一起学习有关JUnit的初学者教程,并且做了一些练习.

As a person has no experience before in unit testing and mocking, I followed beginner tutorials about JUnit with Mockito and I do some practice.

现在,我需要对一些类方法进行单元测试,这些方法在MySQL数据库上执行基本的数据库操作.我不想对数据库进行真正的更改.

Now, I need to unit test some class methods which do basic database operations on a MySQL database. I don't want to make real changes on the database.

在我的代码中:

@InjectMocks private DBConnection dbConnection;
@Mock private DBConnection mockDBConnection;

@Test
public void testDropTable() {

    Mockito.when(mockDBConnection.dropTable()).thenReturn(0);

    // dropTable() returns 0 if table dropped
    int result = dbConnection.dropTable();
    Assert.assertEquals(result, 0);
}

要验证(使用assertEquals())测试结果,我调用了真正的dropTable()方法,并且它实际上删除了表(实际上很明显,因为我正在调用真正的DBConnection实例)

To verify(with assertEquals() ) result of the test, I am calling real dropTable() method, and it really drops table( Actually it is obvious, because I'm calling on real DBConnection instance)

是否有必要在不访问真实数据库的情况下验证类似方法?还是我误解了单元测试和模拟的概念?

Is there anyway to verify the methods like that, without accessing the real database? Or did I misunderstand the concept of Unit Testing and Mocking?

推荐答案

想象一下……您有两辆汽车,一辆是真正的汽车,另一辆是假的(模拟)汽车.现在,您进入真正的汽车,然后开车.你为什么期望不动呢?您对假冒的汽车没有做任何事情,因此,即使您告诉它如果我开始驾驶,也不要移动",这也不会改变当您下车时真正的汽车会移动的事实.

Imagine the following... You have two cars, one is a real car, another is a fake (mock) car. Now you get into the real car and drive off. Why do you expect not to move? You didn't do anything with the fake car, so even if you told it "Do not move if I start driving", this doesn't change the fact that the real car WILL move when you drive off.

在这里,您创建了一个伪造的DBConnection和一个真实的DBConnection.真正的人会做任何真正的人都会做的事情.可以将伪造的东西配置为执行其他操作,就像使用Mockito.when(...)一样.但这并不会改变真正的行为.

Same thing here, you created a fake DBConnection and a real one. The real one will do whatever the real one does. The fake one can be configured to do different stuff, like you did with Mockito.when(...). But that doesn't change the behavior of the real one.

您的测试实际上是没有意义的,因为您在这里的唯一选择是摆脱模拟,因为它没有任何有意义的目的.您不测试模拟.做什么的?这就像制造一辆假车并对其进行测试-它不会告诉您任何有关真车的信息.如果您在该测试中要求它做X,则无需测试假冒汽车即可知道它会做X.

Your test is effectively meaningless, because your only choice here is to get rid of the mock, because it doesn't serve any meaningful purpose. You do not test a mock. What for? That's like creating a fake car and testing that - it doesn't tell you anything about the real car. You do not need to test the fake car to find out that it will do X if you told it to do X in that test.

有两种方法可以测试DBConnection类:

There are two ways you can test your DBConnection class:

a)您可以将其连接到数据库,并检查其是否可以正常工作.当然,这将是一个集成测试,而不是一个单元测试.在某些情况下,您可以使用内存数据库(例如HSQLDB)来加快此测试的速度.但是至少到最后,您可以合理地确定您的代码是否可以执行预期的工作.

a) You can connect it to a database and check that it does what it should. This would, of course, be an integration test and not a unit test anymore. In some cases you can use a in-memory database like HSQLDB to speed up this test. But at least in the end you can be reasonably sure that your code does what it is supposed to be doing.

b)IF和只有IF DBConnection内部有一些对象与数据库进行实际的对话,您可以模拟这些对象,然后测试DBConnection.当然,这只会将您的问题转移到另一层,因为这样您就不确定那些对象是否起作用-如果这些对象起作用,您只会知道DBConnection是起作用的.虽然这是一个很好的认识,但是它并不能回答您的数据库代码最后是否可以工作的问题.

b) IF and only IF DBConnection has some objects internally that do the actual talking to the database, you can, perhaps, mock those and then test DBConnection. Of course, this only moves your problem to another layer, because then you aren't sure that those objects work - you will only know that DBConnection works IF those objects work. While this is good to know, it does not answer the question if your db code will work in the end.

最后,您只能通过连接到数据库来完全测试数据库连接.其他所有内容都不是完整的测试.

In the end, you can only test db connections completely by connecting to a db. Everything else is not a complete test.

这篇关于单元测试(模拟)数据库,如何通过模拟验证数据库方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆