-2

I have the following tests. When I run them separately they pass. If I run all of them only the first passes.

Business Logic gets a JSON response from the APIServiceTask code. It creates an event to post using EventBus. I am writing tests to verify that EventBus is creating the correct calls.

The JSON Reponses class at the end is just the answers I am trying to post. If I run all of the tests, it seems like the loginFailureChangePasswordJSON is the one posted to the business logic.

public class LoginBusinessLogic {
    private static LoginBusinessLogic instance = null;
    APIServiceTask apiServiceTask;

    public static LoginBusinessLogic getInstance(APIServiceTask apiServiceTask) {
        if (instance == null) {
            instance = new LoginBusinessLogic();
            instance.apiServiceTask = apiServiceTask;
        }
        return instance;
    }

    protected void doLogin() {
        EventBus.getDefault().register(this);
        apiServiceTask.execute();
    }

    @Subscribe
    public void onEvent(ServiceResultEvent event) {
        switch (event.event) {
            case failed:
                handleLoginError(event.result);
                break;
            case cancelled:
                EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_CANCELLE, event.result));
                break;
            case error:
                if(event.originatorEvent != LoginEvent.TYPE_TOUCH_TOKEN_DELETE) {
                    EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_ERROR, event.result));
                }
                break;
            default:
                break;
        }
        EventBus.getDefault().unregister(this);
    }

    private void handleLoginError(String error) {
        ErrorModel signInError = new Gson().fromJson(error, ErrorModel.class);
        int statusCode = signInError.getMTBStatusCode();
        String errMsg;
        if (statusCode == 40022) {
            errMsg = signInError.getUserMessage();
        } else {
            errMsg = signInError.getUserMessage().replace("*", "").replace("\"", "");
        }
        if (statusCode == 40001) {
            EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_FAILED, statusCode, errMsg, false, false));
        } else if (statusCode == 40108) {
            EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_FAILED, statusCode, errMsg, true, false));
        }
        else if (statusCode == 40107) {
            EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_FAILED, statusCode, errMsg, false, false));
        } else if (statusCode == 40104) {
            EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_FAILED, statusCode, errMsg, false, true));
        } else {
            EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_FAILED, statusCode, errMsg, false, false));
        }
    }
}

public class APIServiceTask {
    public APIServiceTask(){
    }

    @SuppressWarnings("ConstantConditions")
    public void execute() {

    }
}

public class BusinessLogicTests {
    @Mock
    APIServiceTask service;

    private LoginEvent loginEvent;
    private LoginBusinessLogic loginBusinessLogic;

    @Before
    public void setUp(){
        MockitoAnnotations.initMocks(this);

        loginBusinessLogic = LoginBusinessLogic.getInstance(service);

        EventBus.getDefault().register(this);
    }

    @After
    public void tearDown(){
        EventBus.getDefault().unregister(this);
    }

    @Subscribe
    public void onEvent(LoginEvent event){
        loginEvent = event;
    }

    @Test
    public void badUsernamePasscode(){
        doAnswer(JSONResponses.loginInvalidUsernamePasscodeJSON())
                .when(service).execute();

        loginBusinessLogic.doLogin();
        Assert.assertEquals(40108, loginEvent.mtbStstusCode);
    }

    @Test
    public void accountBlocked(){
        doAnswer(JSONResponses.loginAccountBlockedJSON())
                .when(service).execute();

        loginBusinessLogic.doLogin();
        Assert.assertEquals(40104, loginEvent.mtbStstusCode);
    }

    @Test
    public void temporaryPasscode(){
        doAnswer(JSONResponses.loginTemporaryPasscodeJSON())
                .when(service).execute();

        loginBusinessLogic.doLogin();
        Assert.assertEquals(40109, loginEvent.mtbStstusCode);
    }

    @Test
    public void changedPasscode(){
        doAnswer(JSONResponses.loginFailureChangePasscodeJSON())
                .when(service).execute();

        loginBusinessLogic.doLogin();
        Assert.assertEquals(40107, loginEvent.mtbStstusCode);
    }
}

public class JSONResponses {
    public static Answer loginFailureChangePasscodeJSON(){
        Answer answer = new Answer() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                String result = "{\"MTBStatusCode\":40107, \"UserMessage\":\"Your passcode has changed since last login.\"}";
                EventBus.getDefault().post(new ServiceResultEvent(ServiceResultEvent.EVENT_TYPE.failed, result, 0));
                return null;
            }
        };

        return answer;
    }

    public static Answer loginAccountBlockedJSON(){
        Answer answer = new Answer() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                String result = "{\"Version\":1,\"MTBStatusCode\":40104,\"HttpStatus\":401,\"UserMessage\":\"\\\"Your account is locked due to too many failed login attempts. <br><br><a href=\\\"https://onlinebanking.mtb.com/login/passcodereset\\\">Reset Passcode ></a>\\\"\",\"DeveloperMessage\":\"\\\"Account locked via multi-factor authentication.\\\"\"}";

                EventBus.getDefault().post(new ServiceResultEvent(ServiceResultEvent.EVENT_TYPE.failed, result, 0));
                return null;
            }
        };

        return answer;
    }

    public static Answer loginInvalidUsernamePasscodeJSON(){
        Answer answer = new Answer() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                String result = "{\"Version\":1,\"MTBStatusCode\":40108,\"HttpStatus\":401,\"UserMessage\":\"\\\"User ID or Passcode doesn’t match. Try again.\\\"\",\"DeveloperMessage\":\"\\\"Voyager Error -1073739414 : User ID or Passcode doesn’t match. Try again.\\\"\"}";

                EventBus.getDefault().post(new ServiceResultEvent(ServiceResultEvent.EVENT_TYPE.failed, result, 0));
                return null;
            }
        };

        return answer;
    }

    public static Answer loginTemporaryPasscodeJSON(){
        Answer answer = new Answer() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                String result = "{\"Version\":1,\"MTBStatusCode\":40107,\"HttpStatus\":401,\"UserMessage\":\"\\\"You have logged in with a temporary passcode. Log in to <a href=\\\"http://mtb.com/olb-login\\\">M&T Online Banking</a> to create a new passcode.\\\"\",\"DeveloperMessage\":\"\\\"Password should be changed.\\\"\"}";

                EventBus.getDefault().post(new ServiceResultEvent(ServiceResultEvent.EVENT_TYPE.failed, result, 0));
                return null;
            }
        };

        return answer;
    }
}
  • 1
    Can you show us how `serviceRequest` is declared and populated? – glytching Jan 16 '18 at 16:37
  • Here is my mocks Mock ServiceRequest serviceRequest; Mock APIServiceTask service; Apiservice is passed into LoginBusinessLogic through constructor. I have also added the following line to tests but no luck. Apiservice gets service either in constructor or creates its own depending how you create it. service.setServiceRequest(serviceRequest); – Ken Leiphart Jan 16 '18 at 20:13
  • 1
    It would be easier to read/understand this additional context if you added it to the question by editing the question. Ideally, you would provide a [MCVE](https://stackoverflow.com/help/mcve). – glytching Jan 16 '18 at 20:28
  • I tried to cut down the code to mostly what was needed and made a new project. If the tests in businesslogictests are run seperate all is fine but if you run all then only the first fails. https://github.com/antibound/MockitoTesting @tkruse I don't believe what you mentioned is what the issue is but if I am wrong please let me know now that I added code. – Ken Leiphart Jan 17 '18 at 03:10
  • 1
    Since you do not reuse the mocks, your tests fail for some different obscure reason. Asking people on SO to checkout a medium-sized github project to find a bug in your project is off-topic. Debug yourself until you can make a complete example small enough to fit into the question area. – tkruse Jan 17 '18 at 03:22
  • I wasn't looking to dump my work on others, I am still working on it, I was just hoping there was something pretty obvious I was overlooking. – Ken Leiphart Jan 17 '18 at 03:32
  • updated question with code – Ken Leiphart Jan 17 '18 at 13:32

1 Answers1

0

For anyone interested, it seems the singleton still exists when the other tests run. 2 ways I found to fix it are nulling out the singleton in a separate method or moving the following statement outside of the if in LoginBusinessLogic.

instance.apiServiceTask = apiServiceTask;