弹簧靴中的 Mockito 不会模拟对象



我有一个简单的测试用例,我在春季启动应用程序中使用了Mockito。

用户操作.java

...
@Autowired
Validator nameValidator;
private boolean userOperation(String name) {
    NameStats nameStats = nameValidator.validate(name);
    if (!nameStats.isSuccess()) {
        throw new Exception();
    }
    return true;
}
...

验证器.java

public NameStats validate(String name)
{
    NameStats nameStats = new NameStats();
    // code goes here
    return nameStats;
}

测试用例.java

...
@SpringBootTest
@RunWith(SpringRunner.class)
public class ImportFileOperationTest {
    @Mock
    Validator nameValidator;
    @Mock
    NameStats nameStats;
    @InjectMocks
    UserOperation operation;
    @Test
    public void  ConnectorDelegate0Test() {
        Mockito.when(nameValidator.validate(any(String.class))).thenReturn(nameStats);
        Mockito.when(nameStats.isSuccess()).thenReturn(true);
        operation.userOperation(restConsumerRequest);
    }
}
...

错误:

对于上面的测试用例,我得到了NullPointerException。在跟踪时,我发现测试中的代码行下方返回 null 值。

Mockito.when(nameValidator.validate(any(String.class))).thenReturn(nameStats);

由于空值,当它尝试调用nameStats.isSuccess()时,它会抛出空点异常,即使我嘲笑了对这个函数的响应true

问题:1. 我嘲笑的回答是否正确?2. 为什么模拟函数返回空对象?

更新:

测试用例.java

@SpringBootTest
@RunWith(SpringRunner.class)
public class ImportFileOperationTest {
    @MockBean
    Validator nameValidator;
    NameStats nameStats;
    @InjectMocks
    @Resource
    UserOperation operation;
    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
    }
    @Test
    public void  ConnectorDelegate0Test() {
        nameStats = new nameStats();
        Mockito.when(nameValidator.validate(any(String.class))).thenReturn(nameStats);
        Mockito.when(nameStats.isSuccess()).thenReturn(true);
        operation.userOperation(restConsumerRequest);
    }
}

我尝试手动nameStats创建对象,并期望validate函数返回该对象,但它仍然返回null

任何帮助将不胜感激。

测试应为Mockito驱动或弹簧驱动。弹簧驱动的将具有@SpringBootTest,并且@RunWith(SpringRunner.class)类级别的注释和模拟将使用@MockBean声明或使用Mockito.initMocks显式实例化。模拟驱动的测试将具有@RunWith(MockitoJUnitRunner.class),并且模拟将声明为@Mock和/或注入@InjectMocks。请注意,当实例(如 NameStats(在方法中使用 new 实例化时,注入无济于事。

显示的测试不必@SpringBootTest,因此可以像这样编写为 Mockito 驱动的测试:

@RunWith(MockitoJUnitRunner.class)
public class ImportFileOperationTest {
@Mock
Validator nameValidator;
@InjectMocks
UserOperation operation;
@Test
public void  connectorDelegateTest() {
    NameStats nameStats = new NameStats();
    nameStats.setStats(Stats.SUCCESS);
    Mockito.when(nameValidator.validate(any(String.class))).thenReturn(nameStats);
    operation.userOperation(restConsumerRequest);
}
您需要对所有

类类型使用 @InjectMocks,并且需要@Mock用于该类中的所有关联属性。

例:

 class Product {
 ProductDetails  productDetails;
 }
 class ProductDetails {
 }

上述类的示例测试用例:

@SpringBootTest
@RunWith(SpringRunner.class)
public class ProductTest {
    @Mock
    ProductDetails productDetails;
    @InjectMocks
    Product product;
}

升级到 Spring Boot 2 后遇到了类似的问题。原因在这里解释 https://javadoc.io/static/org.mockito/mockito-core/3.3.3/org/mockito/ArgumentMatchers.html#any-java.lang.Class-

从 Mockito 2.1.0 开始,只允许 的非空实例,因此 null 不再是有效值。

所以 mock 返回 null 或空列表,因为调用是用 anyString() 设置的,并且传递的对象是 null。要匹配值或空值,请使用匹配器any()

相关内容

  • 没有找到相关文章

最新更新