Static factory methods and mockery

How did you reconcile using static factory methods and taunt?

Many people will simply say: do not use static factory methods, use DI instead.

Well, sometimes you cannot escape the static factory methods. Consider the following use cases that should be familiar:

Imagine you have a class called Option, as in scala. You cannot avoid using the static factory method if you want to reuse the same instance for all missing values.

Once you go new Option(null), you create a new option object, you cannot return the same object again and again.

A similar use case is Integer.valueOf()that will reuse integer objects for values ​​below 128. It is impossible to do without using the static factory method.

Another advantage is that factory methods are more visual than new.

So, how do you guys deal with using static factory methods and at the same time want to use inheritance and mocks?

Thanks.

+4
source share
4 answers

Flushing static methods is possible with PowerMock . Consider the following example on a Wiki page :

@Test
public void testRegisterService() throws Exception {
    long expectedId = 42;

    // We create a new instance of test class under test as usually.
    ServiceRegistartor tested = new ServiceRegistartor();

    // This is the way to tell PowerMock to mock all static methods of a
    // given class
    mockStatic(IdGenerator.class);

    /*
     * The static method call to IdGenerator.generateNewId() expectation.
     * This is why we need PowerMock.
     */
    expect(IdGenerator.generateNewId()).andReturn(expectedId);

    // Note how we replay the class, not the instance!
    replay(IdGenerator.class);

    long actualId = tested.registerService(new Object());

    // Note how we verify the class, not the instance!
    verify(IdGenerator.class);

    // Assert that the ID is correct
    assertEquals(expectedId, actualId);
}

, .

+2

, . factory : . , , . /-, .

+1

- -, factory .

, , . , , - JSF, javax.faces.context.FacesContext. , JMockit (, , ):

@Test
public void exampleTest(@Mocked final FacesContext ctx) {
    // Call the code under test, which will at some point
    // call FacesContext.getCurrentInstance(), then add an
    // error message for display in the web page.

    new Verifications() {{
        FacesMessage msg;
        ctx.addMessage(null, msg = withCapture());

        assertEquals("The expected error message.", msg.getSummary());
        assertNotNull(msg.getDetail());
    }};
}

Faces.getCurrentInstance() - factory, mock FacesContext, .

+1

factory .

java DI , Integer.valueOf() :

  • integerType.valueOf(), integerType ,

  • typeSystem.getInteger().valueOf() typeSystem

  • environment.getTypeSystem().getInteger().getFactory() environment .

, , .

, - - factory, . . , , - , .

, System.out StandardConsole , Console, Console .

(And if you do, I would even add that you can continue and configure your version control system to reject any attempts to execute code containing the string "System.out". [Evil grin]) sub>

0
source

Source: https://habr.com/ru/post/1618144/


All Articles