Похоже, вы пытаетесь объединить несколько различных тестов в одном выражении it
. Вот как я мог бы подойти к этому:
it 'creates company and user' do
expect { post :create, params }
.to change { User.count }.by(1)
.and change { Company.count }.by(1)
end
it 'assigns instance variables' do
post :create, params
expect(assigns(:company)).to eq(Company.last)
expect(assigns(:user)).to eq(User.last)
end
it 'calls create_timeline_event with newly created company and user' do
allow(some_object).to receive(:create_timeline_event)
post :create, params
expect(some_object)
.to have_received(:create_timeline_event)
.with(Company.last, User.last)
end
Обратите внимание, что эти тесты будут медленными, потому что они попали в базу данных. Другой подход к этому заключается в использовании макетов. Это выглядело бы примерно так:
let(:params) { ... }
let(:company) { instance_double(Company) }
let(:user) { instance_double(User) }
before do
allow(Company).to receive(:create).and_return(company)
allow(User).to receive(:create).and_return(user)
allow(some_object).to receive(:create_timeline_event)
post :create, params
end
it 'creates company and user' do
expect(Company).to have_received(:create).with(company_params)
expect(User).to have_received(:create).with(user_params)
end
it 'assigns instance variables' do
expect(assigns(:company)).to eq(company)
expect(assigns(:user)).to eq(user)
end
it 'calls create_timeline_event with newly created company and user' do
expect(some_object)
.to have_received(:create_timeline_event)
.with(company, user)
end
Эти тесты вообще не затрагивают базу данных, что означает, что они будут выполняться намного быстрее.
«Удобные конструкторы» для многих типов создают объект, который автоматически «автоматически высвобождается», т.е. новый объект будет сохранен текущим NSAutoreleasePool. Вам не нужно вручную освобождать эти объекты - они будут освобождены, когда текущий NSAutoreleasePool будет освобожден / истощен.
См. Эту страницу для описания вспомогательных конструкторов и как управлять памятью для них.
http : //www.macdevcenter.com/pub/a/mac/2001/07/27/cocoa.html? page = 3
Просто следуйте основному правилу управления памятью: если вы «владеете» переменной, вы должны в конечном итоге отказаться от владения. Вы вступаете во владение путем: создания объекта (alloc / new / copy) или, в частности, вступления во владение (retain). Во всех этих случаях вам необходимо освободить его.
Если вам нужен объект, чтобы остаться, вы должны стать владельцем этого объекта. Так что, если вы знаете, что вам нужен только номер для этого метода (например, чтобы передать его в массив или что-то еще), используйте вспомогательный метод и просто оставьте его при этом. Если вы хотите по какой-то причине сохранить номер (и, например, переменную экземпляра), вы можете безопасно выделить / инициализировать его.
Если вы выпустите что-то, что вам не принадлежит, вы получите ошибку времени выполнения.
Правило простое, с очень немногими исключениями:
Если селектор, возвращающий объект, имеет слово «new», «alloc», «retain "или" скопировать "в него, то вы являетесь владельцем возвращенного объекта и несете ответственность за его освобождение, когда вы закончите.
В противном случае вы не владеете им и не должны его освобождать. Если вы хотите сохранить ссылку на не принадлежащий объекту, вам следует вызвать - [NSObject retain]
в этом экземпляре. Теперь вы «владеете» этим экземпляром, поэтому вы должны вызвать - [NSObject release]
для экземпляра, когда вы закончите с ним. Таким образом, вы не являетесь владельцем экземпляра, возвращенного - [NSNumber numberWithInt:]
, и не должны вызывать -release
для него, когда вы закончите. Если вы хотите сохранить возвращаемый экземпляр за пределами текущей области (на самом деле за пределами срока действия текущего экземпляра NSAutoreleasePool
), вы должны -сохранить его
.
В терминах RegEx, Питер Хоси очень хорошо об этом пишет в своем блоге . Вы являетесь владельцем возвращенного экземпляра объекта, если селектор метода соответствует этому регулярному выражению:
/^retain$|^(alloc|new)|[cC]opy/
Конечно, окончательной ссылкой является Руководство по программированию управления памятью для какао .
Если вы хотите сохранить возвращаемый экземпляр за пределами текущей области (на самом деле за пределами срока действия текущего экземпляра NSAutoreleasePool
), вы должны -сохранить его
.
В терминах RegEx, Питер Хоси очень хорошо об этом пишет в своем блоге . Вы являетесь владельцем возвращенного экземпляра объекта, если селектор метода соответствует этому регулярному выражению:
/^retain$|^(alloc|new)|[cC]opy/
Конечно, окончательной ссылкой является Руководство по программированию управления памятью для какао .
Если вы хотите сохранить возвращаемый экземпляр за пределами текущей области (на самом деле за пределами срока действия текущего экземпляра NSAutoreleasePool
), вы должны -сохранить его
.
В терминах RegEx, Питер Хоси очень хорошо об этом пишет в своем блоге . Вы являетесь владельцем возвращенного экземпляра объекта, если селектор метода соответствует этому регулярному выражению:
/^retain$|^(alloc|new)|[cC]opy/
Конечно, окончательной ссылкой является Руководство по программированию управления памятью для какао .