2

I have the following scenario in Spring :

public class ClassA{

@Autowired
private ClassB classB;
}

I'm using (Autowiring to be more precise) ClassA in my Test class. But what I'd like to do somehow is to modify ClassB just for my Junit, so with that, When ClassA is autowired in my test class, it loads the modified ClassB (instead of the original one).

Is there a way to achive that?

Columb1a
  • 463
  • 2
  • 11
  • 25
  • I think you need 2 configurations, one for normal execution and one for your test case. – Alex Oct 25 '17 at 03:36
  • So basically, you say to create a copy of ClassA, and autowire a modified classB, and then use it in my junit?. I've done that before, but this time I would like to avoid that approach. I'm trying to think if there's a Spring mechanism that could help me to do what I want. – Columb1a Oct 25 '17 at 03:39
  • This is precisely why it's a good idea to use an interface and an implementing class. In fact, best practice is to use constructor injection, which means that you can run your unit tests without needing Spring at all (just pass a mock to the constructor). – chrylis -cautiouslyoptimistic- Oct 25 '17 at 03:42
  • To do so via Spring, you must create separate configuration (xml or annotation one) for your test and your normal execution. Set a sub class of ClassB for ClassA in your test configuration. No need to rewrite ClassA at all. – Alex Oct 25 '17 at 03:44

1 Answers1

1

Can't think of another way to do this without Bean Configuration. You can configure this in 2 ways:

First:

@Configuration
public class AppConfig {

  @Bean
  public ClassB classB() {
    return new ClassB() {
      // this is a subclass that inherits everything from ClassB, so override what you want here
    }
  }
}

Second: (taken from here)

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

  // do this if you only want the modified classB in 1 place
  @Configuration
  static class TestConfig {
      @Bean
      public ClassB classB () {
          return new ClassB() {
            // same as the first
          }
      }
  }

  @Test
  public void testMethod() {
    // test
  }
}

Finally, you could create a new interface ClassB and ClassBImpl in your main folder and ClassBTestImpl in your test folder. You still need to use one of the configuration.

Yoshua Nahar
  • 1,304
  • 11
  • 28