简体   繁体   English

如何在@BeforeClass测试方法调用的静态方法中使用bean

[英]How to use bean in static method which is called by @BeforeClass test method

Let's suppose I have a test class A which extends from class B . 假设我有一个从B类扩展的测试类A This class A has one method with @BeforeClass annotation: 此类A具有一个带有@BeforeClass批注的方法:

@BeforeClass
public static void setUp(){
    createFakeData();
}

The method createFakeData() is in class B and its function is to create an object in database. 方法createFakeData()在类B ,其功能是在数据库中创建对象。

In order to do that, I have a bean in class B : 为了做到这一点,我在B类中有一个bean:

@Autowired
private DummyObjectsFactory dummyObjectsFactory;

And the content of the method createFakeData() could be something like that which returns a FakeData object: 方法createFakeData()的内容可能类似于返回FakeData对象的内容:

public FakeData createFakeData() throws Exception
{
    return dummyObjectsFactory.createFakeData();
}

The problem I'm facing is that the @BeforeClass method has to be static, that means that the createFakeData method has to be static too. 我面临的问题是@BeforeClass方法必须是静态的,这意味着createFakeData方法也必须是静态的。 But I cannot set that method to static because my bean dummyObjectsFactory will be always null . 但是我不能将该方法设置为static,因为我的bean dummyObjectsFactory将始终为null

How can I make my createFakeData method static avoiding my dummyObjectsFactory bean to be not null? 如何使我的createFakeData方法成为静态方法,以避免我的dummyObjectsFactory bean不为null?

As far as I know, that is not permitted in JUnit. 据我所知,这在JUnit中是不允许的。 However you can do some things for arrange it. 但是,您可以做一些安排工作。

First, you can use TestNG , which allows to do exactly what you want. 首先,您可以使用TestNG ,它可以完全执行您想要的操作。

If that is not an option, instead of using @BefloreClass annotation, you can use @Before . 如果这不是一个选择,则可以使用@Before而不是使用@BefloreClass注释。 The difference between both is that @BeforeClass executes the method before all the tests while @Before executes the method before each test. 两者之间的区别在于@BeforeClass在所有测试之前执行该方法,而@Before在每个测试之前执行该方法。 If you use @Before , I would annotate the class with @Transactional in order to delete the data saved in the database. 如果使用@Before ,我将使用@Transactional注释类,以便删除保存在数据库中的数据。

In the end, if you don't want to execute the method for each test, you can use @Before and flat the call: 最后,如果您不想为每个测试执行该方法,则可以使用@Before并平整调用:

@Before
public void init(){
    if(!fakeDataCalled){
        createFakeData();
        fakeDataCalled=true;
    }
}

I believe you want to annotate your test class (B) with @RunWith(SpringRunner.class) so that the autowiring happens correctly. 我相信您想使用@RunWith(SpringRunner.class)注释测试类(B),以便正确进行自动装配。

Take a look at section 15.4.4 in the Spring Reference . 看一下Spring Reference中的 15.4.4节。 You can also just browse to that page and search for "RunWith" 您也可以浏览到该页面并搜索“ RunWith”

Caveats: 注意事项:

  1. I don't like static methods. 我不喜欢静态方法。 They tend to make unit testing difficult. 它们往往使单元测试变得困难。
  2. I don't like extending tests to make other tests. 我不喜欢将测试扩展到其他测试。 I find it easier to make each test standalone and use composition for any shared functionality (ie make utility classes for shared test functionality that reside in the test source tree). 我发现使每个测试独立运行并为任何共享功能使用组合更容易(例如,使驻留在测试源树中的共享测试功能的实用工具类)。
  3. I don't like my unit tests depending on autowiring. 我不喜欢依靠自动装配的单元测试。 I mock all the dependencies and inject them with either reflection or the @InjectMocks annotation. 我模拟了所有依赖项,并使用反射或@InjectMocks批注注入它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM