junit 测试ServiceA并将对ServiceB的所有调用替换为MockServiceB

kkih6yb8  于 2022-11-11  发布在  其他
关注(0)|答案(1)|浏览(129)

是否可以测试serviceA的方法,并告诉测试环境用mockServiceB替换从serviceA到serviceB的所有调用?
这是我想测试的方法(ServiceA.java):

@Inject
    ServiceB serviceB;

    public boolean tokenExists(ItemModel item) throws Exception {
        try {
            List<ItemModel > items = serviceB.getItems();
            String token = item.getToken();
            return items.stream().filter(i -> i.getToken().equals(token)).findFirst().isPresent();
        } catch (ApiException e) {
            throw new Exception(500, "Data could not be fetched.", e);
        }
    }

由于serviceB.getItems()将导致REST调用,因此我想将对serviceB的调用替换为自定义的mockServiceB,其中我只是从json文件加载模拟数据,如下所示(TestServiceA.java):

@InjectMock
    ServiceB serviceB;

    @ApplicationScoped
    public static class ServiceB {

        private ObjectMapper objMapper = new ObjectMapper();;

        public List<ItemModel> getItems() throws IOException {
            final String itemsAsJson;

            try {
                itemsAsJson= IOUtils.toString(new FileReader(RESOURCE_PATH + "items.json"));
                objMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                List<Item> items= objMapper.readValue(itemsAsJson, objMapper.getTypeFactory().constructCollectionType(List.class, ItemModel.class));
                return items;
            } catch (IOException e) {
                throw e;
            }
        }
    }

然后测试tokenExists方法,如下所示(TestServiceA.java):

@Test
    public void testTokenExists() {
        try {
            Assertions.assertTrue(this.serviceA.tokenExists(this.getTestItem()));
        } catch (Exception e) {
            fail("exception");
        }
    }

然而,当我运行测试testTokenExists时,它仍然调用原来的serviceB.getItems()

kd3sttzy

kd3sttzy1#

你需要在ServiceA类里面模拟serviceB,你有两种不同的选择:

首先您可以使用whiteboxreflection,并将模拟的serviceB分配给ServiceA

public class TestExample {
    @Mock
    private ServiceB mockedServiceB;
    private ServiceA serviceA;

    @Before
    public void setUp() {
       serviceA = new ServiceA();
    }

    @Test
    public void shouldDoSomething() {
        // Arrange
        Whitebox.setInternalState(serviceA, "serviceB", mockedServiceB);
        when(serviceB.getItems()).thenReturn(list);

       // Act & Assert
       Assertions.assertTrue(serviceA.tokenExists(this.getTestItem()));
    }
}

第二个

您可以使用@InjectMocks

public class TestExample {
    @Mock
    private ServiceB mockedServiceB;
    @InjectMocks
    private ServiceA serviceA;

    @Before
    public void setUp() {
       serviceA = new ServiceA();
    }

    @Test
    public void shouldDoSomething() {
       // Arrange
        List<Item> list = new ArrayList<>();
        list.add(new Item(...)); // add whatever you want to the list
        when(serviceB.getItems()).thenReturn(list);

       // Act & Assert
       Assertions.assertTrue(serviceA.tokenExists(this.getTestItem()));
    }
}

注意:也准备好你的跑步者

相关问题