Как определить, что фиктивный метод вызывается ноль раз
Я пытаюсь проверить следующий метод:
//AuthenticationMiddleware Middleware which handles all of the authentication.
func AuthenticationMiddleware(context context.ContextIntf, w web.ResponseWriter, r *web.Request, next web.NextMiddlewareFunc) {
//Check if url is one that doesn't need authorization. If not than send them to the login page.
for _, url := range AuthMWInstance.GetInfo().nonAuthURLs {
if url.Method == r.Method && strings.Contains(r.URL.Path, url.DomainName) {
next(w, r)
return
}
}
if errSt := CheckForAuthorization(context, r, w); errSt != nil {
responses.Write(w, responses.Unauthorized(*errSt))
return
}
defer context.GetInfo().Session.SessionRelease(w)
next(w, r)
}
В этом случае есть SessionRelease
который вызывается, если r
содержит URL, который требует авторизации, и эта авторизация прошла успешно.
Может быть важно знать, что:
type MiddlewareSt struct {
//NonAuthUrls URLs that can be accessed without a token.
nonAuthURLs []url.URLSt
}
type MiddlewareIntf interface {
GetInfo() *MiddlewareSt
CheckTokenAndSetSession(context context.ContextIntf, r *web.Request, w web.ResponseWriter,
token string, scope string, remoteAddr string) *errors.ErrorSt
}
var AuthMWInstance MiddlewareIntf
и это CheckForAuthorization
возвращаемое значение в конечном итоге опирается на AuthMWInstance
Моя тестовая стратегия
- Создать заглушку промежуточного программного обеспечения для инициализации
AuthMWInstance
к тому, что просто возвращаетсяnil
заCheckTokenAndSetSession
(конечно, с установкой сеанса, абстрагированной от создания самого объекта-заглушки, который имеетSession
) иMiddlewareSt
полный подделкиnonAuthURLs
заGetInfo()
- Создать макет
session.Store
что для всех тестов, кроме теста на здравомыслие, ожидается нулевой вызовSessionRelease
,
Вероятно, стоит отметить (но предполагается), что я использую библиотеки testify, издевательства для насмешек и утверждений.
Тест
Реализуется таким образом:
func TestAuthenticationMiddleware(t *testing.T) {
// bring in the errors
sdkTesting.InitErrors()
// create/set up the test doubles
// mock session
sessionMock := new(testing_mock.MockStore)
// temporarily set AuthMWInstance to a stub
instance := AuthMWInstance
AuthMWInstance = &StubMiddlewareInstance{
Session: sessionMock,
}
// AuthMWInstance.Session
defer func() { AuthMWInstance = instance }()
// fake ResponseWriter
w := new(StubResponseWriter)
// fake web requests
requestWithoutAuth := new(web.Request)
requestWithoutAuth.Request = httptest.NewRequest("GET",
"http://example.com/logout",
nil,
)
// do tests here
t.Run("AuthorizationNotRequired", func(t *testing.T) {
// place expectations on sessionMock, namely that it does
// **not** invoke `SessionRelease`
sessionMock.On("SessionRelease", w).
Times(0)
AuthenticationMiddleware(new(context.Context),
w,
requestWithoutAuth,
web.NextMiddlewareFunc(func(web.ResponseWriter, *web.Request) {}))
sessionMock.AssertExpectations(t)
})
}
Поведение во время выполнения
Происходит следующий ложный сбой: , Это буквально как будто вместо того, чтобы делать:
sessionMock.On("SessionRelease", w).
Times(0)
, Я был как:
sessionMock.On("SessionRelease", w).
Once()
НОТА session.Store.SessionRelease
ничего не возвращает, поэтому я даже не удосужился использовать Return()
,
Я утверждаю, что это должно быть вызвано ровно ноль раз, верно?
1 ответ
Я чувствую себя немного глупо за это.
Проблема заключалась в том, что я беспокоился с
sessionMock.AssertExpectations(t)
когда я мог бы просто сказать
sessionMock.AssertNotCalled(t, "SessionRelease", w)
(Документация по этому методу здесь)
Выполнение последнего решило проблему и сделало именно то, что я пытался выполнить.