简体   繁体   English

创建一个包含对象的模拟列表

[英]Create a mocked list with objects

I want to create a JUnit test with tests mocked objects:我想用测试模拟对象创建一个 JUnit 测试:

public class BinCountryCheckFilterImplTest {

    private RiskFilterService riskFilterService = null;

    @Before
    public void beforeEachTest() {

        List<RiskFilters> list = new ArrayList<RiskFilters>();

        riskFilterService = Mockito.mock(RiskFilterService.class);

        // put here list of List<RiskFilters> and return it 
    }

    @Test
    public void testBinCountryCheckFilterImpl() {

        List<RiskFilters> filter_list = riskFilterService.findRiskFiltersByTerminalIdAndType(11, "test");
         // do something                
    }    
}

How I can return the list List<RiskFilters> when RiskFilterService is calle?调用RiskFilterService时如何返回列表List<RiskFilters>

Second attempt:第二次尝试:

public class BinCountryCheckFilterImplTest {

    private RiskFilterService riskFilterService = null;

    @Mock
    List<RiskFilters> mockList = new ArrayList<RiskFilters>();

    @BeforeClass
    public void beforeEachTest() {

        //if we don't call below, we will get NullPointerException
        MockitoAnnotations.initMocks(this);

        mockList.add(new RiskFilters());

        riskFilterService = Mockito.mock(RiskFilterService.class);
    }

    @Test
    public void testBinCountryCheckFilterImpl() {

        when(riskFilterService.findRiskFiltersByTerminalIdAndType(anyInt(), anyString())).thenReturn(mockList);

        List<RiskFilters> filter_list = riskFilterService.findRiskFiltersByTerminalIdAndType(11, "BinCountryCheckFilter");

    }
}

But I get NPE for riskFilterService .但我得到riskFilterService的 NPE。 Looks like the method with annotation @test is called before @BeforeClass.看起来带有注释@test的方法在@BeforeClass之前被调用。

Well you provided very less information.好吧,您提供的信息非常少。 BUt let me put through但是让我通过

you must be having BinCountryCheckFilter class.你必须有BinCountryCheckFilter class。 Please Initialise it in your test class and add annotation @InjectMocks请在您的测试 class 中初始化它并添加注释@InjectMocks

@InjectMock
private BinCountryCheckFilter binCountryCheckFilter;

take riskFilterService = Mockito.mock(RiskFilterService.class); riskFilterService = Mockito.mock(RiskFilterService.class); out of @BeforeClass and put it openly.@BeforeClass中取出并公开。

But this will just mock your class and will not test anything.但这只会模拟您的 class 并且不会测试任何内容。 One thing you can test is no of calls made.您可以测试的一件事是没有拨打电话。 See below见下文

verify(mockList, times(1)).yourMethodName(); 

or add following in your test or before method或在您的测试或方法之前添加以下内容

when(riskFilterService.yurMethodName).thenReturn(your Return value);

This way you will be able to mock the data you want.这样你就可以模拟你想要的数据。 Let me know if any other clarity needed.让我知道是否需要任何其他澄清。

I am not sure of your JUnit version but you can remove我不确定您的 JUnit 版本,但您可以删除

comelete @BeforeClass from your code now and立即从您的代码中获取@BeforeClass

 @Mock
    List<RiskFilters> mockList = new ArrayList<RiskFilters>();

too.也。

When a List or any other Collection is required in a unit test, the first question to ask yourself is: should I create a mock for it, or should I create a List or a Collection containing mocks.当单元测试中需要 List 或任何其他 Collection 时,要问自己的第一个问题是:我应该为它创建一个 mock,还是应该创建一个包含 mock 的 List 或 Collection。

When the logic being tested is not using the list, but just passing the list than you can mock it.当被测试的逻辑不使用列表,而只是传递列表而不是你可以模拟它时。

Otherwise it is usually better not to mock a List or a Collection but to create a normal one containing mocked objects because it can become very difficult to know which methods of the List or Collections need to be stubbed.否则,最好不要模拟 List 或 Collection,而是创建一个包含模拟对象的普通列表,因为很难知道 List 或 Collections 的哪些方法需要存根。 Which methods are called when using a for loop to iterate the items, when using an iterator on them, when using a stream on them, ... ?使用 for 循环迭代项目时调用哪些方法,在它们上使用迭代器时,在它们上使用 stream 时,...? I often use Collections.singletonList or Arrays.asList with mocked parameters to initialise lists when writing unit tests.在编写单元测试时,我经常使用带有模拟参数的 Collections.singletonList 或 Arrays.asList 来初始化列表。

I see that you mock the list and then you call the add method to add data to it while setting up the test.我看到您模拟了列表,然后在设置测试时调用 add 方法向其中添加数据。 It doesn't make sense to add data to a mocked list.将数据添加到模拟列表是没有意义的。 You can use Mockito.when to return it when it should be returned, but then you would get in trouble because you might need to stub more methods and it would be hard to know which ones (isEmpty, size, ...).您可以使用 Mockito.when 在应该返回它的时候返回它,但是您会遇到麻烦,因为您可能需要存根更多方法并且很难知道哪些方法(isEmpty,size,...)。 That you are adding a dataobject to list probably means the method being tested is not just passing the list but will access the data in it.您将数据对象添加到列表可能意味着正在测试的方法不仅传递列表,而且将访问其中的数据。 In that case, don't mock the list, but mock the data objects which you put in it.在这种情况下,不要模拟列表,而是模拟您放入其中的数据对象。

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

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