英文:
Mockito: verify arguments passed to constructor
问题
我正在尝试弄清楚如何验证传递给Mockito模拟构造函数的参数。我的代码的简化版本如下:
class Mocked {
Mocked(String first, String second, int value) {
}
}
class Target {
void testMe() {
new Mocked("Hello", "World", 99);
}
}
@Test
public void test_Target() {
try (
MockedConstruction<Mocked> mockedNew = mockConstruction(Mocked.class);
) {
new Target().testMe();
Mocked mocked = mockedNew.constructed().get(0);
// TODO: 验证传递给模拟构造函数的所有参数
}
}
* 我试图测试的类是"Target"
* Target使用"Mocked"类的实例。在实际代码中,我将使用实际的Mocked实例,但是为了测试的目的,我想将其模拟出来,以便我可以隔离地测试"Target",我使用了mockConstruction构造函数来做到这一点。
在我的代码的最终版本中,传递给Mocked构造函数的参数并不是硬编码的。相反,将会有一些业务逻辑来推导它们,所以我想验证它们是否已经正确地推导出来了。但是该如何做呢?
我在Google上搜索的所有示例都没有显示如何做到这一点,而且org.mockito.Mockito.verify()似乎没有一种方法可以测试构造函数。
我唯一能想到的解决方案是添加模拟初始化函数,将参数复制到局部变量中。但是这涉及使这些变量有效地成为final(所以是final的单元素数组)和丑陋的类型转换。肯定有比这更好的办法!
我漏掉了什么?
英文:
I'm trying to work out how to verify the parameters passed to a mocked constructor in Mockito. A simplified version of my code is:
class Mocked {
Mocked(String first, String second, int value) {
}
}
class Target {
void testMe() {
new Mocked("Hello", "World", 99);
}
}
@Test
public void test_Target() {
try (
MockedConstruction<Mocked> mockedNew = mockConstruction(Mocked.class);
) {
new Target().testMe();
Mocked mocked = mockedNew.constructed().get(0);
// TODO: verify all arguments passed to mocked
}
}
- The class I'm trying to test is "Target"
- Target uses an instance of the "Mocked" class. In real code code I'll want to use an actual instance of Mocked, but for the purposes of testing I want to mock it out so I can test "Target" in isolation of "Mocked". I've used the mockConstruction construct to do this.
In my final version of my code the arguments passed to the Mocked constructor are not hardcoded. Instead there will be some business logic to derive them, so and I want to verify they have been derived out correctly. But how?
None of the examples I've Googled show show me how to do this, and org.mockito.Mockito.verify()
doesn't appear to have a way to test a constructor.
The only solution I can see is to add mock initialiser function that copies the argument into local variables. But this involves making those variables effectively final (so final one element array) and ugly casts. Surely there has to be something better than that!
What have I missed?
答案1
得分: 1
你可以使用 Junit 或你选择的测试库来对传递给 mockedConstructor
的 context
参数运行断言,该参数将包含传递给构造函数的参数列表。 (请注意,它们都将被存储为 Object
,因此您需要进行强制类型转换) 例如:
try (MockedConstruction<Mocked> mockedConstructor = mockConstruction(Mocked.class, (mock, context) -> {
assertEquals("Hello", (String) context.arguments().get(0));
assertEquals("World", (String) context.arguments().get(1));
assertEquals(99, (int) context.arguments().get(2));
}))
{
new Target().testMe();
}
英文:
You can run assertions using Junit or your testing library of choice on the context
argument passed into the mockedConstructor, which will have a list of the arguments passed into the constructor. (Note that they will all be stored as Object
, so you will need to cast them) e.g.
try (MockedConstruction<Mocked> mockedConstructor = mockConstruction(Mocked.class, (mock, context) -> {
assertEquals("Hello", (String) context.arguments().get(0));
assertEquals("World", (String) context.arguments().get(1));
assertEquals(99, (int) context.arguments().get(2));
}))
{
new Target().testMe();
}
答案2
得分: 0
根据我所知,使用Mockito API 是不可能实现这一点的。
你可以尝试进行设计更改,在这个新的 MockedFactory
类中负责创建 Mocked
对象。你可以为你的测试创建一个 MockMockedFactory
并将其注入到目标对象中以使用。你将能够验证被测试类调用的这个工厂的方法。虽然不是最好的方法,会增加样板代码,但是是可行的。
另外,我猜想新创建的对象如果不返回,那么测试就不会有问题。如果你正在测试的方法不是一次性做太多事情的话,值得考虑一下。也许进行一些重构可以使它更容易进行测试。
或许这个链接会有帮助:https://groups.google.com/g/mockito/c/WqPlcNrvbOw?pli=1
英文:
As far as I know, this is not possible using the Mockito API.
You can try a design change where a new MockedFactory
class is responsible for creating Mocked
objects. You can create a MockMockedFactory
for your tests and inject it into Target to use. You will be able to verify the methods called on this factory by the class under test. Not the nicest, adds boilerplate code, but works.
Also, I guess the newly created object is not returned as testing would not be a problem then. It is worth considering if the method you are testing isn't too big doing too many things at once. Maybe some other refactors could help make it more testable.
Or maybe this one: https://groups.google.com/g/mockito/c/WqPlcNrvbOw?pli=1
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论