Spring Boot单元测试服务,手动测试通过,但模拟服务失败

时间:2016-11-17 16:19:11

标签: spring-mvc junit spring-boot mockito

为了测试我的服务逻辑,我必须在3个存储库中设置一些初始测试数据。测试的这一部分正在运行,但随后服务应该发生的更新永远不会发生在存储库中并且测试失败。希望如果我按照服务逻辑显示测试,那么我会更清楚我想要做什么。

我想我可能错过了一些与正确模拟服务有关的注释。我认为模拟的服务没有连接到它的模拟存储库。我不知道要添加哪些具体配置。

以下是代码:

试验:

package portal.services;

import static org.junit.Assert.assertEquals;

@RunWith(SpringJUnit4ClassRunner.class)
@DataJpaTest
public class TestRunServiceTest {
    @MockBean
    private TestRunService testRunService;
    @Autowired
    private TestRunRepository testRunRepository;
    @Autowired
    private TestCaseRepository testCaseRepository;
    @Autowired
    private TestToolRepository testToolRepository;
    @Autowired
    private TestSuiteRepository testSuiteRepository;

    TestCase testCase = new TestCase();
    TestTool testTool = new TestTool();
    TestSuite testSuite = new TestSuite();
    TestRun testRun = new TestRun();

    @Before 
    public void createTestData(){
        // create the test case
        testCase.setId(1);
        testCase.setName("Agent Charities");
        testCaseRepository.save(testCase);

        // create test tool
        testTool.setId(1);
        testToolRepository.save(testTool);

        //create test suite
        testSuite.setId(1);
        testSuite.setTestCase(testCase);
        testSuite.setTestTool(testTool);
        testSuiteRepository.save(testSuite);

        // create test run
        testRun.setTestSuite(testSuite);
        testRun.setStartDateTime(new Date());
        testRun.setEndDateTime(new Date());
    }

    @Test
    public void aggregateDataCountWhenResultIsPass(){

        // test run result is true with 5 data items
        testRun.setResult(true);
        testRun.setGeneratedDataCount((long)5);
        testRunService.add(testRun);

        // test run result is false with 3 data items
        testRun.setResult(false);
        testRun.setGeneratedDataCount((long)3);
        testRunService.add(testRun);

        // TEST FAILS BECAUSE testRunService did not persist any data
        System.out.println(testRunRepository.count()); //output = 0

        // test tool and test case repositories should show count of 5
        assertEquals((long)5, testCaseRepository.findByid((long)1).getGeneratedDataCount().longValue());
        assertEquals((long)5, testToolRepository.findByid((long)1).getGeneratedDataCount().longValue());
        // test failed with NullPointerException, GeneratedDataCount was not updated by testRunService
    }

}

服务

public interface TestRunService {
    Iterable<TestRun> listAllTestRuns();
    TestRun getTestRunById(Integer id);
    ResponseEntity<?> add(@RequestBody TestRun input);
}


@Service
public class TestRunServiceImpl implements TestRunService {

    private TestRunRepository testRunRepository;
    private TestSuiteRepository testSuiteRepository;
    private TestCaseRepository testCaseRepository;
    private TestToolRepository testToolRepository;

    @Autowired
    public void setTestRunRepository(TestRunRepository testRunRepository) {
        this.testRunRepository = testRunRepository;
    }
    @Autowired
    public void setTestSuiteRepository(TestSuiteRepository testSuiteRepository) {
        this.testSuiteRepository = testSuiteRepository;
    }
    @Autowired
    public void setTestCaseRepository(TestCaseRepository testCaseRepository) {
        this.testCaseRepository = testCaseRepository;
    }
    @Autowired
    public void setTesttOOLRepository(TestToolRepository testToolRepository) {
        this.testToolRepository = testToolRepository;
    }

    @Override
    public Iterable<TestRun> listAllTestRuns() {
        return testRunRepository.findAll();
    }

    @Override
    public TestRun getTestRunById(Integer id) {
        return testRunRepository.findOne((long)id);
    }

    @Override
    public ResponseEntity<?> add(@RequestBody TestRun input) {

        // save te test run
        TestRun result = testRunRepository.save(input);
        URI location = ServletUriComponentsBuilder
                .fromCurrentRequest().path("/{id}")
                .buildAndExpand(result.getId()).toUri();

        // update runtime total for test TOOL
        TestSuite suite = testSuiteRepository.findByid(result.getTestSuite().getId());
        TestTool tool = testToolRepository.findByid(suite.getTestTool().getId());
        tool.setTotalRuntime(result.getRuntimeMilliseconds());

        // if the run was a pass, update the generated data count as well
        if (result.getResult() == true){
            tool.setGeneratedDataCount(result.getGeneratedDataCount());
        }
        // save updated test tool information
        testToolRepository.save(tool);

        // update runtime total for test CASE
        TestCase testCase = testCaseRepository.findByid(suite.getTestCase().getId());
        testCase.setTotalRuntime(result.getRuntimeMilliseconds());

        // if the run was a pass, update the generated data count as well
        if (result.getResult() == true){
            testCase.setGeneratedDataCount(result.getGeneratedDataCount());
        }
        // save updated test case information
        testCaseRepository.save(testCase);

        return ResponseEntity.created(location).build();        
    }
}

问题是我知道这项服务是通过手动测试和检查数据库来实现的,所以我无法让单元测试通过,这让我感到很沮丧。

2 个答案:

答案 0 :(得分:0)

我不确定为什么要为您的服务使用@MockBean批注。

您可以尝试在setup方法中构建一个正确的TestRunService对象并使用它吗?

例如:

@Before 
public void createTestData(){
     //set up service
     testRunService = new TestRunServiceImpl();
     //invoke repository setters on your service object
     //data creation     
}

答案 1 :(得分:0)

  1. 使用SpringRunner.class代替SpringJUnit4ClassRunner.class,然后将@MockBean更改为@Autowired@DataJpaTest是必需的。

  2. 如果有一些必需的配置,例如ContextConfiguationPersistenceConfig,则需要使用@Import({ContextConfiguation.class,...})

  3. 进行导入
  4. 使用@TestConfiguration

    创建模拟bean

    @TestConfiguration 静态类TestRunServiceImplTextContextConfig {     @豆角,扁豆     公共TestRunService testRunService(){         返回新的TestRunServiceImpl();     } }

我使用Spring Boot 2.1.1进行了测试。