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

强制TestNG为每个方法测试创建新实例

左丘嘉言
2023-03-14

根据以下链接:https://stackoverflow.com/a/20056622/1623597 https://stackoverflow.com/a/15640575/1623597TestNG不会在每个方法测试中创建新实例。

我有spring boot应用程序。我需要编写集成测试(控制器、服务、存储库)。有时为了创建新的测试用例,我需要数据库中的一些实体。为了忘记数据库中任何预定义的实体,我决定模拟存储库层。我刚刚实现了ApplicationContextInitializer,它在类路径中查找所有JPA存储库,并将它们的模拟添加到spring上下文中。

我有一个新问题,我的模拟创建一次,每一个ControlllerTest(扩展AbstractTestNGSpringContext测试)。测试上下文只创建一次,所有方法的模拟实例都是一样的。现在,我有了

//All repos are mocked via implementation of ApplicationContextInitializer<GenericWebApplicationContext>
// and added to spring context by
//applicationContext.getBeanFactory().registerSingleton(beanName, mock(beanClass));   //beanClass in our case is StudentRepository.class
@Autowired
StudentRepository studentRepository;

//real MyService implementation with autowired studentRepository mock
@Autowired
MyService mySevice;

@Test
public void test1() throws Exception {
    mySevice.execute();     //it internally calls studentRepository.findOne(..); only one time
    verify(studentRepository).findOne(notNull(String.class));
}

//I want that studentRepository that autowired to mySevice was recreated(reset)
@Test
public void test2() throws Exception {
    mySevice.execute();     //it internally calls studentRepository.findOne(..); only one time
    verify(studentRepository, times(2)).findOne(notNull(String.class)); //I don't want to use times(2)
    //times(2) because studentRepository has already been invoked in test1() method

}

@Test
public void test3() throws Exception {
    mySevice.execute();     //it internally calls studentRepository.findOne(..); only one time
    verify(studentRepository, times(3)).findOne(notNull(String.class)); //I don't want to use times(3)
}

我需要为下一个方法增加次数(N)。我知道这是testng实现,但我试图为自己找到好的解决方案。对于我的服务,我使用构造函数自动连接,所有字段都是最终字段。

问题:

>

  • 是否可以强制testng为每个方法测试创建新实例?我可以为每个方法测试重新创建spring上下文吗?

    我可以通过我的代理为每个模拟的存储库创建我的自定义代理并在@Beforemethod方法中重置模拟吗?

  • 共有1个答案

    丰誉
    2023-03-14

    实际上,我不需要在上下文中创建新的存储库模拟实例,我只需要重置它们的状态。到目前为止,我认为Mockito.reset(mock)只是创建新的实例并将其分配给引用mock。但这不是真的。Mockito.reset的真正行为只是清除mock的当前状态,而不创建新的mock实例。

    我的解决方案:

    import org.springframework.data.repository.Repository;
    
    @Autowired
    private List<Repository> mockedRepositories;
    
    @BeforeMethod
    public void before() {
        mockedRepositories.forEach(Mockito::reset);
    }
    

    这段代码会自动连接所有在Application ationContext初始化器中被模拟的repos,并重置它们的状态。现在我可以使用验证()没有时间(2)

    @Test
    public void test2() throws Exception {
        mySevice.execute()
        verify(studentRepository).findOne(notNull(String.class));
    }
    
     类似资料:
    • 如果运行模式是,如何强制TestNG为每个方法创建新的测试类实例? JUnit自动执行,但TestNG在方法之间重用相同的实例。

    • 问题内容: 在Selenium-webdriver中创建webdriver实例的最佳实践是什么?每个测试方法,每个测试类别或每个测试运行一次? 启动它们似乎相当(非常!)昂贵,但是在测试之间保持开放很可能会泄漏测试方法之间的信息。 还是有其他选择-单个webdriver实例是单个浏览器窗口(不包括弹出窗口),还是有一种方法可以从给定的驱动程序实例启动新窗口/会话? 谢谢马特 问题答案: 我发现在使

    • 问题内容: 我想编写一个TestNG测试,以确保在特定条件下引发了异常,如果未引发异常,则使测试失败。有没有一种简单的方法,而不必创建额外的布尔变量? 有关此主题的相关博客文章:http : //konigsberg.blogspot.com/2007/11/testng-and- expectedexceptions-ive.html 问题答案: 在最常见的情况下很有用: 您期望会引发特定的异常

    • 我是斯卡拉诺布。 我目前尝试使用specs2为基于Play(Scala)的web应用程序创建功能测试。示例本身很简单,即: 我想实现的是为每个示例提供一组定义的测试数据,其中一些数据已经保留在数据库中。因此,我需要围绕每个示例进行设置和拆卸方法,以准备用例类,用适当的数据填充它并保留其中的一些数据,以便该示例可以从定义的数据库状态开始。最终,我想要一个插件机制,其中插件为一组示例定义了测试数据(将

    • 我已经写了一个以太坊智能合约在坚实的语言。为了测试,我可以使用Ganache运行一个本地节点,并使用在其上部署我的合同。 我想用JavaScript测试我的合同。我想为每个测试创建一个新的契约实例。 我在我的项目中创建了一个测试文件: 我运行它与。它基本上是摩卡,但是松露通过与智能合同的JavaScript连接为您定义了。 松露<代码>合同功能和摩卡的<代码>描述功能几乎一样,有一个我不明白的小变