当前位置: 首页 > 知识库问答 >
问题:

未被mockito模拟的自动连线bean上的空指针

施念
2023-03-14

我有一个服务类需要进行单元测试。该服务有一个上载方法,该方法反过来调用其他更新数据库的服务(自动连线bean)。我需要模拟其中一些服务,还有一些服务需要按原样执行。

@Service
public class UploadServiceImpl implements UploadService{
  @Autowired
  private ServiceA serviceA;

  @Autowired
  private ServiceB serviceB;

  public void upload(){
    serviceA.execute();
    serviceB.execute():

    //code...
}

在上面的例子中,我需要模拟ServiceA,但是我希望ServiceB按原样运行并执行它的功能。我的JUnit测试如下所示:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringBootTest(classes=Swagger2SpringBoot.class) 
public class UploadServiceTest {
  @Mock
  private ServiceA serviceA;

  @InjectMocks
  private UploadServiceImpl uploadService;

  @Before
  public void init() {
    MockitoAnnotations.initMocks(this);
  }

  @Test
  public void testUpload(){
    uploadService.upload();

  }

当我执行这个,我得到NPE在serviceB执行();UploadServiceImpl.

有什么问题吗?

注意:我没有指定被模拟对象的行为,因为我真的不在乎,而且被模拟对象的默认行为是什么都不做。

谢谢!

共有3个答案

汝繁
2023-03-14

您所面临的问题是由于使用了@InjectMocks注释造成的。@InjectMocks标记了应该在其上执行注入的字段。Mockito将尝试仅通过构造函数注入、setter注入或属性注入来注入模拟-按此顺序。如果任何给定的注入策略失败,则Mockito不会报告失败。

因此,在您尝试注入模拟时,只有一个模拟bean存在,而另一个bean ServiceA没有被注入。要解决这个问题:

您可以尝试根本不使用@InjectMocks,而是为要模拟的方法传递一个模拟对象,同时将其余的自动连接对象传递到构造函数中。例子:

在这里测试我传递一个模拟对象和一个自动连线对象。

@RunWith(MockitoJUnitRunner.class)
public class SampleTestServiceImplTest {

@Mock
private SampleClient sampleClient;
@Autowired
private BackendService backendService ;

private BackendServiceImpl backendServiceimpl;

@Before
void setUp() {
    backendServiceimpl = new BackendServiceImpl(sampleClient, backendService);
}

另一种方法是使用@Autowired注释和@injectmock@Autowired@injectmock一起使用,它将注入被模拟的类,Autowired注释添加该类可能具有的任何其他依赖项。

答复来自:https://medium.com/@vatsalsinghal/autowired-and-injectmocks-in-tandem-a424517fdd29

缪阎宝
2023-03-14

添加

  @Mock
  private ServiceB serviceB;

创建缺失服务的可注入模拟,就像处理服务A一样。

白祺然
2023-03-14

通常当单元测试时,你想模拟一个类的所有外部依赖。这样单元测试就可以保持独立,并专注于被测试的类。

然而,如果您想将Spring自动装配与Mockito模拟混合使用,一个简单的解决方案是同时使用@InjectMocks@Autow哎进行注释:

  @InjectMocks
  @Autowired
  private UploadServiceImpl uploadService;

这样做的最终效果是,首先Spring将自动连接bean,然后Mockito将立即用可用的模拟覆盖模拟的依赖关系。

 类似资料:
  • 当我运行这个测试时,我会得到以下输出(如果我的服务不需要另一个bean,我会得到预期的输出) 由于这个响应,我在line.andExpect(content().contentType(Mediatype.application_json_utf8));上遇到了问题。当我检查response body时(因为body也是空的) 再现问题的示例项目在这里

  • 我在服务类中的自动连线 Bean 上收到 。我尝试自动连线的类是Cassandra Repository。 我的主要类应用程序.java 我的Cassandra配置CassandraConfig.java 我的仓库(dao)产品价格仓库.java 我的服务类ProductService.java 我的pom.xml 我的理解是,注释应该拿起存储库并根据注释创建 bean。ProductServic

  • 我创建了一个特殊的应用程序ontext-test.xml在我的测试类中使用它。 应用程序上下文测试。xml 现在,我想使用我的作为自动安装的Bean并将其注入到我的模拟中。 TodoDaoTest.java 这是我的TodoDao类TodoDao。Java语言 当我执行我的测试方法时,我得到了一个java。com上的lang.NullPointerException。梅德赫利菲。教程。托多利斯特。

  • 我希望创建使用Spring上下文和模拟存储库bean的测试。我使用的是Spring Boot 1.3。2.构建快照JUnit Mockito。 以下是我的测试配置类: 此配置的目的是将OfferPresository从Spring上下文中排除并对其进行模拟,由于此,我将能够编写使用Spring上下文和模拟数据库存储库的测试。 这是我的测试课: 测试和测试配置目录为: 我的应用程序配置和包含Offe

  • 我有一个 Rest Controller 类,其中我正在自动布线服务层。现在我想模拟测试类中的服务层,但在运行我的测试类 控制器代码 测试类 我是JUnit5和Mockito的新手。有人能告诉我哪里错了吗?