spring 3 autowiring and junit testing

前端 未结 4 1815
[愿得一人]
[愿得一人] 2020-12-12 17:23

My code:

@Component
public class A {
    @Autowired
    private B b;

    public void method() {}
}

public interface X {...}

@Component
public class B impl         


        
相关标签:
4条回答
  • 2020-12-12 17:46

    This forum discussion makes sense to me. You can declare your private member b as a type of InterfaceB which is implemented by the class B (ie: service-oriented) then declare a MockB class would also implement the same interface. In your test environment application context, you declare MockB class and your production application context you declare the normal B class and in either case, the code for class A does not need to be changed since it will be auto-wired.

    0 讨论(0)
  • 2020-12-12 17:52

    You can inject the field via reflection using Spring's ReflectionTestUtils.setField (or the junit extension PrivateAccessor) or you can create a mock application context and load that. Though for a simple unit (non-integration) test, I favor using reflection for simplicity.

    0 讨论(0)
  • 2020-12-12 17:59

    Here's an example of how I got my tests working with Spring 3.1, JUnit 4.7, and Mockito 1.9:

    FooService.java

    public class FooService {
        @Autowired private FooDAO fooDAO;
        public Foo find(Long id) {
            return fooDAO.findById(id);
        }
    }
    

    FooDAO.java

    public class FooDAO {
        public Foo findById(Long id) {
            /* implementation */
        }
    }
    

    FooServiceTest.java

    @RunWith(MockitoJUnitRunner.class)
    public class FooServiceTest {
        @Mock private FooDAO mockFooDAO;
        @InjectMocks private FooService fooService = new FooService();
    
        @Test public final void findAll() {
            Foo foo = new Foo(1L);
            when(mockFooDAO.findById(foo.getId()).thenReturn(foo);
    
            Foo found = fooService.findById(foo.getId());
            assertEquals(foo, found);
        }
    }
    
    0 讨论(0)
  • 2020-12-12 18:02

    I want to test in isolation class A.

    You should absolutely mock B, rather than instantiate and inject an instance of B. The point is to test A whether or not B works, so you should not allow a potentially broken B interfere with the testing of A.

    That said, I highly recommend Mockito. As mocking frameworks go, it is extremely easy to use. You would write something like the following:

    @Test
    public void testA() {
        A a = new A();
        B b = Mockito.mock(B.class); // create a mock of B
        Mockito.when(b.getMeaningOfLife()).thenReturn(42); // define mocked behavior of b
        ReflectionTestUtils.setField(a, "b", b); // inject b into the B attribute of A
    
        a.method();
    
        // call whatever asserts you need here
    }
    
    0 讨论(0)
提交回复
热议问题