单元测试Spring抛出BeanNotOfRequiredTypeException

时间:2018-11-16 12:17:57

标签: java spring unit-testing exception

运行测试类会引发以下异常:

BeanNotOfRequiredTypeException: Bean named 'myServiceImpl' is expected to be of type 'MyServiceImpl' but was actually of type 'com.sun.proxy.$Proxy139'

此错误仅在单元测试中引发,程序本身可以工作。

我的界面

public interface MyService {

    public String testMethod();

}

我的实施

@Service
public class MyServiceImpl implements MyService{

    @Autowired
    private TransactionRepository transactionRepo;

    @Autowired
    private AccountRepository accountRepository;

    @Autowired
    private BankAccountStatementFactory baStatementFactory;

    public String myMethod() {
        return "Run My Method";
    }

}

我的单元测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class DeleteMeTest{


    @Mock
    private TransactionRepository transactionRepo;

    @Mock
    private AccountRepository accountRepository;

    @Mock
    private BankAccountStatementFactory baStatementFactory;

    @InjectMocks
    @Resource
    MyServiceImpl myService;


    @org.junit.Before
    public void setUp() throws Exception {
        // Initialize mocks created above
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void test() {
        myService.myMethod();
        System.out.println("My Unit Test");
    }

}

运行此测试类将引发以下异常:

BeanNotOfRequiredTypeException: Bean named 'myServiceImpl' is expected to be of type 'MyServiceImpl' but was actually of type 'com.sun.proxy.$Proxy139'

这里的解决方案是将接口(而不是实现)注入到单元测试中,但这将不允许我注入模拟。

那是因为@InjectMocks批注需要实现。当我尝试将模拟内容注入接口时,出现以下异常:

Cannot instantiate @InjectMocks field named 'myService'! Cause: the type 'MyService' is an interface.

请明确一点,所有这些工作从一开始就起作用,并且在我重新打包课程后变得很糟糕。这可能是原因,但不是100%确定。

关于可能导致此BeanNotOfRequiredTypeException的原因的任何提示?

谢谢!

2 个答案:

答案 0 :(得分:0)

因为它是单元测试,所以您不需要Spring 恕我直言。

以这种方式简单地初始化测试的类:

@InjectMocks
MyServiceImpl myService = new MyServiceImpl();

您还可以删除以下注释:

@RunWith(SpringRunner.class)
@SpringBootTest

答案 1 :(得分:0)

如果您确实需要使用Spring (在您的帖子中尚不清楚在单元测试中使用Spring的原因),则可以尝试取消代理bean:

为代理和bean分别声明:

@Resource
MyServiceImpl proxy;

@InjectMocks
MyServiceImpl myService;

然后在setUp()中对其进行初始化:

@org.junit.Before
public void setUp() throws Exception {
    // Initialize mocks created above
    myService = (MyServiceImpl)((TargetSource) proxy).getTarget();
    MockitoAnnotations.initMocks(this);

}