سؤال

أحاول اختبار وحدة تحكم تحتوي على كائن أمر مع ملزمة البيانات.

كائن الأمر لديه خدمة حقن فيه.

ولكن عندما أحاول اختبار كائن الأمر، لم يتم العثور على طريقة الخدمة المحقونة أبدا لأنها ليست "حقن"

هل هناك طريقة لاستكشاف خدمة داخل كائن أمر؟

طريقة اختبار

void testLoginPasswordInvalid() {
    mockRequest.method = 'POST'
    mockDomain(User, [new User(login:"freddy", password:"realpassword")])
    mockLogging(UserService) // userService mocked
    MockUtils.prepareForConstraintsTests(LoginCommand)

    def userService = new UserService()
    def user = userService.getUser("freddy")//Gets called and returns the mockDomain
    assert userService.getUser("freddy")//Passes

    def cmd = new LoginCommand(login:"freddy", password:"letmein")
    cmd.validate() // Fails (userService is nevr injected)
    controller.login(cmd)
    assertTrue cmd.hasErrors()
    assertEquals "user.password.invalid", cmd.errors.password
    assertEquals "/store/index", renderArgs.view
}

لم يتم العثور على طريقة GetUser ()

Cannot invoke method getUser() on null object
java.lang.NullPointerException: Cannot invoke method getUser() on null object

شفرة

طريقة تسجيل الدخول إلى وحدة التحكم التي يتم استدعاؤها،

def login = { LoginCommand cmd ->
  if(request.method == 'POST') {
     if(!cmd.hasErrors()){
       session.user = cmd.getUser()
       redirect(controller:'store')
     }
     else{
       render(view:'/store/index', model:[loginCmd:cmd])
     }
  }else{

    render(view:'/store/index')
  }
}

كائن الأمر لديه حقن "userservice" في ذلك.

يدعو Validator إلى هذا الموقع للعثور على مستخدم

 class LoginCommand {

    def userService

    String login
    String password

    static constraints = {
      login blank:false, validator:{ val, cmd ->
          if(!cmd.userService.getUser()){
             return "user.not.found"
          }
      }
 }

يشبه userservice.getuser () مثل هذا.

class UserService {

    boolean transactional = true

    User getUser(String login) {
        return User.findByLogin(login)

    }
}
هل كانت مفيدة؟

المحلول

يتم حقن الخدمة باستخدام الربيع AutoWire-by-name. (grep شجرة مصدر الشجر ل autowire للعثور على جزء من التعليمات البرمجية لطيفة، يمكنك استخدامه للحصول عليه ل AutoWire لوحدات التحكم الخاصة بك من أجلك في اختبارات التكامل.) هذه الوظائف الوحيدة في اختبارات التكامل، حيث يوجد سياق تطبيق الربيع الذي يحتوي على الفاصوليا التي يمكن حقنها.

في اختبارات الوحدة، عليك أن تفعل هذا بنفسك لأن هناك أرض الربيع تحيط بأشياءك. هذا يمكن أن يكون الألم، لكنه يمنحك بعض الفوائد:

1) من السهل حقن إصدارات وهمية من الخدمات - على سبيل المثال، باستخدام Expando - من أجل تحديد سلوك خدمات التحكم في وحدة التحكم الخاصة بك عن كثب، والسماح لك باختبار منطق وحدة التحكم فقط بدلا من وحدة التحكم والخدمة معا. (يمكنك بالتأكيد القيام به الأخير في اختبار الوحدة أيضا، ولكن لديك خيار كيفية الأسلاك.)

2) يجبرك أن تكون صريحا حول التبعيات في وحدة التحكم الخاصة بك - إذا كنت تعتمد على ذلك، فسوف تظهرها اختباراتك. هذا يجعلهم مواصفات أفضل لسلوك وحدة التحكم الخاصة بك.

3) يمكنك أن تسخر فقط قطع المتعاونين الخارجيين تحكم يعتمد على. هذا يساعد الاختبارات الخاصة بك تكون أقل هشاشة - أقل عرضة للحاجة إلى تغيير عندما تتغير الأمور.

إجابة قصيرة: تحتاج طريقة الاختبار الخاصة بك cmd.userService = userService خط.

نصائح أخرى

ما يقوله جون هو في العلامة. مثال واحد قد يكون:

def mockUsers = [new User(login:"freddy", password:"realpassword")]
mockDomain(User, mockUsers)

def userService = [getUser:{String login -> mockUsers[0]}] as UserService

def cmd = new LoginCommand (/*arguments*/)
cmd.userService = userService

يمكنك البحث عن طرق أخرى لكائنات وهمية في http://groovy.codehaus.org/groovy+mocks.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top