Conteng Evolved

Stuff, mostly software development stuff

Change User Within JUnit Test Case in Google AppEngine

Google AppEngine (Java) provides ability to mock UserService in JUnit test cases with the help of LocalUserServiceTestConfig. However, switching user within a test case is not so simple.

Switching user within a test case allows simulation of multi-user scenarios such as:

  1. Bob creates BobMessage.
  2. Cat logs in and is able to see BobMessage.
  3. Dan logs in and is not able to see BobMessage.

Solution

Create a loginAs(String, Closure) method in Groovy to switch the injected UserService within Spring MVC controller object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@Before
public void setUp() {
    super.setUp()
    new LocalServiceTestHelper(new LocalUserServiceTestConfig())
            .setEnvAttributes([
            'com.google.appengine.api.users.UserService.user_id_key': 'bob-101'
    ])
            .setEnvEmail('bob@bob.com')
            .setEnvAuthDomain('bob.com')
            .setEnvIsLoggedIn(true)
            .setUp()
}

void loginAs(String username, Closure closure) {
    UserService mockUserService = mock(UserService)
    when(mockUserService.currentUser).thenReturn(
            new User("${username}@test", 'test', "${username}-id")
    )

    UserService backupUserService = controller.userService
    controller.userService = mockUserService
    closure.call()
    controller.userService = backupUserService
}

@Test
void 'multi user test case'() {
    // default user is bob@bob.com as configured in @Before
    assertEquals('bob@bob.com', controller.userService.currentUser.email)

    // login as 'ace' and execute assertion in closure
    loginAs('ace', {
        assertEquals('ace@test', controller.userService.currentUser.email)
    })

    // login as 'cat' and execute assertion in closure
    loginAs('cat', {
        assertEquals('cat@test', controller.userService.currentUser.email)
    })

    // post loginAs method, user reverts to value set in @Before
    assertEquals('bob@bob.com', controller.userService.currentUser.email)
}

Requirements

  • Google App Engine (Java)
  • SpringMVC (@Controller with injected UserService)
  • Groovy – while this example was coded in Groovy, it is not really a requirement. You can always do similar stuff in Java.

Comments