如何在RestController类中模拟私有变量

huangapple go评论59阅读模式
英文:

how to mock private variable in RestController class

问题

以下是您要翻译的内容:

我正在使用Spring进行一些Web单元测试。是否有一种方法可以模拟在@PostConstruct中设置的MyProcessor实例?我尝试过使用@MockBean,但它被设置为null,然后出现空指针异常?

我正在使用工厂根据某些布尔标志实例化MyProcessor。但如果有其他完全不同的方法可以使我的测试更清晰,我也可以接受。

请注意,我正在使用Junit 5。

public class Controller {

    private final AProcessorFactory factory;

    @Value("${tt.f.processor.async}")
    private boolean isAsync;

    private MyProcessor myProcessor;

    public Controller(final AProcessorFactory factory) {
        this.factory = factory;
    }

    @PostConstruct
    public void init() {
        myProcessor = factory.getInstance(isAsync);
    }

}


@WebMvcTest(Controller.class)
public class ControllerTest{

    @MockBean
    private MyProcessor processor;

    @MockBean
    private AProcessorFactory factory;

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void test() throws Exception {

        when(processor.process(any(Request.class), any(String.class)))
                .thenReturn(new TestResponse("123", SUCCESS, "", ""));

    }

}
英文:

I am doing some web unit testing with Spring. is there a way I can mock the instance of MyProcessor which get set in @PostConstruct? I tried with @MockBean but it gets set as null and getting null pointer exception?

I am using a factory to instantiate MyProcessor based on some boolean flag. But if there is a different approach altogether that would make my test cleaner, I am open to ideas.

Please Note I am using Junit 5.

public class Controller {

    private final AProcessorFactory factory;

    @Value("${tt.f.processor.async}")
    private boolean isAsync;

    private MyProcessor myProcessor;

    public Controller(final AProcessorFactory factory) {
        this.factory= factory;
    }

    @PostConstruct
    public void init() {
        myProcessor = factory.getInstance(isAsync);
    }

}


@WebMvcTest(Controller.class)
public class ControllerTest{

    @MockBean
    private MyProcessor processor;


    @MockBean
    private AProcessorFactory factory;

    @Autowired
    private MockMvc mockMvc;


    @Test
    public void test() throws Exception {           

        when(processor.process(any(Request.class), any(String.class)))
                .thenReturn(new TestResponse("123", SUCCESS, "", ""));

}

答案1

得分: 1

看起来你的 myProcessor 实际上是由你的 AProcessorFactoryPostConstructinit() 方法中构建的。

你需要为你的 AProcessorFactory 模拟提供一种行为。

首先,你可能会想在构造函数中设置你的 myProcessor,因为 @PostConstructinit() 方法没有特殊的上下文加载逻辑。

public class Controller {

    @Value("${tt.f.processor.async}")
    private boolean isAsync;

    private MyProcessor myProcessor;

    public Controller(final AProcessorFactory factory) {
        this.myProcessor = factory.getInstance(isAsync);
    }
}

你可以在测试的 @Before 步骤中指定这一点。

@MockBean
private AProcessorFactory factory;

@Before
public void setUp() {
    when(processor.process(any(Request.class), any(String.class)))
        .thenReturn(new TestResponse("123", SUCCESS, "", ""));
    when(factory.getInstance(any())).thenReturn(processor);
}

Spring 将会注册你的 AProcessorFactory 模拟,并加载适当的行为。

英文:

It looks like your myProcessor is actually built by your AProcessorFactory in a PostConstruct init() method.

You'll want to provide a behavior for your AProcessorFactory mock.

First, you would probably want to set up your myProcessor in your constructor as the @PostConstruct init() method has no special context loading logic with it.

public class Controller {

    @Value("${tt.f.processor.async}")
    private boolean isAsync;

    private MyProcessor myProcessor;

    public Controller(final AProcessorFactory factory) {
        this.myProcessor = factory.getInstance(isAsync);
    }
}

You can specify this in a @Before step in your test.

 @MockBean
 private AProcessorFactory factory;

 @Before
 public void setUp() {
     when(processor.process(any(Request.class), any(String.class)))
            .thenReturn(new TestResponse("123", SUCCESS, "", ""));
     when(factory.getInstance(any())).thenReturn(processor)
 }

Spring will register your AProcessorFactory mock that has been loaded with the appropriate behaviors.

huangapple
  • 本文由 发表于 2020年9月2日 23:17:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/63708547.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定