TestNG学习-依赖注入

简介: TestNG学习-依赖注入

   TestNG支持两种不同类型的依赖项注入:本地(由TestNG本身执行)和外部(由诸如Guice(Google依赖注入框架)类的依赖项注入框架执行)。

1. 本地依赖注入

   TestNG允许在方法中声明其他参数。发生这种情况时,TestNG将自动用正确的值填充这些参数。依赖注入可以在以下地方使用:

任何@Before方法或@Test方法都可以声明ITestContext类型的参数。
任何@AfterMethod方法都可以声明ITestResult类型的参数,该参数将反映刚刚运行的测试方法的结果。
任何@Before和@After方法(@BeforeSuite和@AfterSuite除外)都可以声明XmlTest类型的参数,该参数包含当前的<test>标记。
任何@BeforeMethod(和@AfterMethod)都可以声明java.lang.reflect.Method类型的参数。此参数将接收此@BeforeMethod完成之后(或在为@AfterMethod运行的方法之后)将调用的测试方法。
任何@BeforeMethod都可以声明Object[]类型的参数。此参数将接收测试方法的参数的列表,该列表可以由TestNG注入,例如java.lang.reflect.Method或来自@DataProvider。
任何@DataProvider都可以声明ITestContext或java.lang.reflect.Method类型的参数。后一个参数将接收将要调用的测试方法。

可以使用@NoInjection批注关闭注入:    

public class NoInjectionTest {
  @DataProvider(name = "provider")
  public Object[][] provide() throws Exception {
      return new Object[][] { { CC.class.getMethod("f") } };
  }
  @Test(dataProvider = "provider")
  public void withoutInjection(@NoInjection Method m) {
      Assert.assertEquals(m.getName(), "f");
  }
  @Test(dataProvider = "provider")
  public void withInjection(Method m) {
      Assert.assertEquals(m.getName(), "withInjection");
  }
}

下表总结了可以为TestNG注解本地注入的各种参数类型:

Annotation  ITestContext   XmlTest   Method   Object[]   ITestResult 
BeforeSuite Yes No No No No
BeforeTest Yes Yes No No No
BeforeGroups Yes Yes No No No
BeforeClass Yes Yes No No No
BeforeMethod Yes Yes Yes Yes Yes
Test Yes No No No No
DataProvider Yes No Yes No No
AfterMethod Yes Yes Yes Yes Yes
AfterClass Yes Yes No No No
AfterGroups Yes Yes No No No
AfterTest Yes Yes No No No
AfterSuite Yes No No No No

2. 外部依赖注入

   如果使用的是Guice,TestNG提供了一种使用Guice模块注入测试对象的简便方法:

@Guice(modules = GuiceExampleModule.class)
public class GuiceTest extends SimpleBaseTest {
  @Inject
  ISingleton m_singleton;
  @Test
  public void singletonShouldWork() {
    m_singleton.doSomething();
  }
}

在这个示例中,GuiceExampleModule会将接口ISingleton绑定到一些具体的类:

public class GuiceExampleModule implements Module {
  @Override
  public void configure(Binder binder) {
    binder.bind(ISingleton.class).to(ExampleSingleton.class).in(Singleton.class);
  }
}

如果希望在指定应使用哪些模块实例化测试类时更灵活,则可以指定一个模块工厂:

@Guice(moduleFactory = ModuleFactory.class)
public class GuiceModuleFactoryTest {
  @Inject
  ISingleton m_singleton;
  @Test
  public void singletonShouldWork() {
    m_singleton.doSomething();
  }
}

模块工厂需要实现接口IModuleFactory:

public interface IModuleFactory {
 /**
   * @param context The current test context
   * @param testClass The test class
   *
   * @return The Guice module that should be used to get an instance of this
   * test class.
   */
  Module createModule(ITestContext context, Class<?> testClass);
}

   说明:工厂将通过TestNG实例化测试上下文和测试类的实例。createModule方法返回一个Guice模块,该模块需要知道如何实例化此测试类。可以使用测试上下文找到有关环境的更多信息,例如在testng.xml中指定的参数等。

   通过父模块和guice-stage suite参数,可以更灵活的结合Guice功能进行使用。guice-stage允许选择用于创建父类注入的Stage。默认值是DEVELOPMENT。其他允许的值为PRODUCTION和TOOL。是在test.xml文件中定义父模块的方法:  

<suite parent-module="com.example.SuiteParenModule" guice-stage="PRODUCTION">
</suite>

   对于给定的suite集,TestNG将仅创建一次该模块,还将使用该模块获取特定测试的Guice模块和模块工厂的实例,然后将为每个测试类创建子注入器。通过这种方法,您可以在父模块中声明所有公共绑定,也可以在模块和模块工厂中注入在父模块中声明的绑定。 以下是相关示例:

package com.example;
public class ParentModule extends AbstractModule {
  @Override
  protected void conigure() {
    bind(MyService.class).toProvider(MyServiceProvider.class);
    bind(MyContext.class).to(MyContextImpl.class).in(Singleton.class);
  }
}
package com.example;
public class TestModule extends AbstractModule {
  private final MyContext myContext;
  @Inject
  TestModule(MyContext myContext) {
    this.myContext = myContext
  }
  @Override
  protected void configure() {
    bind(MySession.class).toInstance(myContext.getSession());
  }
}
<suite parent-module="com.example.ParentModule">
</suite>
package com.example;
@Test
@Guice(modules = TestModule.class)
public class TestClass {
  @Inject
  MyService myService;
  @Inject
  MySession mySession;
  public void testServiceWithSession() {
    myService.serve(mySession);
  }
}

   说明:如上图所示,ParentModule为MyService和MyContext类声明了绑定。然后使用构造函数注入将MyContext注入到TestModule类中,该类也声明对MySession的绑定。然后将测试XML文件中的parent-module设置为ParentModule类,这样来启用在TestModule中的注入。

   然后在TestClass中,会看到两次注入:* MyService-绑定取自ParentModule 、* MySession-绑定取自TestModule。此配置可确保在suite中的所有测试都将在同一会话实例上运行,MyContextImpl对象每个suite仅创建一次, 这可以为suite中的所有测试配置通用的环境状态。

   欢迎多多交流~

相关文章
|
Java 测试技术 数据库
Spring 单元测试(Junit)
Spring 单元测试(Junit)
|
6月前
|
Java 测试技术 Maven
Spring整合JUnit实现单元测试
本文介绍了如何在Java开发中使用Spring与JUnit进行单元测试。首先,设置JUnit和Spring环境,创建待测试的业务逻辑类,如MyService。接着,编写JUnit测试类MyServiceTest,使用`@RunWith(SpringJUnit4ClassRunner.class)`和`@ContextConfiguration`注解,注入并测试MyService的方法。此外,借助Mockito模拟依赖对象,以及使用Spring TestContext框架进行集成测试,确保测试的隔离性和环境的稳定性。通过这些方法,可以提升代码质量和测试效率。
79 1
|
6月前
|
JavaScript Java 测试技术
单元测试使用依赖注入
单元测试使用依赖注入
108 2
|
6月前
|
运维 Java 测试技术
spring 单元测试 Junit
spring 单元测试 Junit
83 2
|
6月前
|
Java 测试技术 Spring
spring之单元测试:JUnit
【1月更文挑战第16天】 一、整合JUnit5 1、搭建子模块 2、引入依赖 3、添加配置文件 4、添加java类 5、测试 二、整合JUnit4 1、添加依赖 2、测试
113 4
|
Java 数据库 Spring
Spring Boot 学习研究笔记(四) -Junit 5 中注解特性
Spring Boot 学习研究笔记(四) -Junit 5 中注解特性
|
敏捷开发 测试技术 数据库
PowerMock(一):PowerMock的基本使用
您好,我是码农飞哥,感谢您阅读本文!本文主要介绍PowerMock的基本使用。
1463 0
|
监控 Java 测试技术
spring单元测试之Mockito
Mockito 是一个针对 Java 的单元测试模拟框架,它与 EasyMock 和 jMock 很相似,都是为了简化单元测试过程中测试上下文 ( 或者称之为测试驱动函数以及桩函数 ) 的搭建而开发的工具
|
Java 测试技术 Spring
spring学习13-使用junit4进行单元测试续
spring学习13-使用junit4进行单元测试续
93 0
spring学习13-使用junit4进行单元测试续