From jamesmead44 at gmail.com Tue May 1 08:58:05 2007 From: jamesmead44 at gmail.com (James Mead) Date: Tue, 1 May 2007 13:58:05 +0100 Subject: [mocha-developer] mocking missing methods In-Reply-To: <46366BF1.8080209@tastapod.com> References: <45ED45B1.2030102@tastapod.com> <1db558f00703070214g10d9c286rf6e12562c6c8bda@mail.gmail.com> <1db558f00704250933j3a1a8532u62d3bb6e9b5a34b2@mail.gmail.com> <57c63afe0704251429q4f3a1008l70a63e4129537072@mail.gmail.com> <1db558f00704251503n4736efc9h7a833f6607fadb2b@mail.gmail.com> <57c63afe0704251619n62d43621rbff8a5f48209b0f8@mail.gmail.com> <4AB9CF7E-2EBC-4A70-B571-58AEEFF7F286@jayfields.com> <57c63afe0704271620p610a8d63n2cdc4f3a7ca266ba@mail.gmail.com> <46366BF1.8080209@tastapod.com> Message-ID: <1db558f00705010558l2ee1a2e9nf64c65cad327cd42@mail.gmail.com> Wow - it's great to have so much input on this... On 30/04/07, Dan North wrote:> This is timely for me. I've been thinking about exactly this vocabulary > recently, but in the context of BDD rather than (as well as?) mocking. > It's about the terms "is a" and "has a" and how they restrict your > thinking because they don't really cover the idea of roles. You need > "acts like a" or "behaves like a" to really describe multiple hats. > > In this instance, I would like something like "acts like a" (in fact, > David and I were discussing "quacks_like" in another conversation). I really like "quacks_like". :-) > Here's some thinking-out-loud: > > So: > mock_sheep.responds_like(Sheep.new) > or > mock_sheep.acts_like(Sheep.new) > > This should be additive: > mock_ninja_sheep.acts_like(Sheep.new) > mock_ninja_sheep.acts_like(Ninja.new) > or even: > mock_ninja_sheep.acts_like(Sheep.new, Ninja.new) I'm not clear why you would want to be able to do this if Sheep & Ninja are distinct classes. > One problem I see is a hard-to-detect semantic error: > mock_sheep.acts_like(Sheep) # oops - meant Sheep.new Agreed. > Also, what about modules? This is fugly: > mock_countable_sheep.acts_like(Sheep.new.extend(Enumerable)) # yuk A good point, but this would only be an issue if you were extending a Sheep instance at runtime. If the Sheep class includes Enumerable at class definition time, any Sheep instance will respond_to? Enumerable methods. However, it would be nice to have a solution that covers extending a Sheep instance at runtime. I'm not so sure that there is anything wrong with your "yuk" example given that it is a bit of an edge case. > So, we need a way of saying: "fail intuitively if the mocked object > wouldn't respond to this call". > > Ok, end of ramble. Here's my ill-thought-out proposal: > > mock_sheep = mock("sheep") # give it a name > mock_sheep.responds_like_type(Sheep, ...) # uses #instance_method > mock_sheep.responds_like_instance(ninja, ...) # uses #respond_to? > mock_sheep.responds_like(cheese) # depends if cheese is class/module I like this. One thing I don't think I explained about my equivalent of "responds_like_type" i.e. "responds_like(instance_of(Sheep))" was that it would use a sneaky trick to construct an instance of the class without calling initialize purely in order to be able to use "respond_to?" instead of "instance_method"... def instance_of(klass) class_without_initialize = Class.new(klass) do def initialize(*args) # intentionally left blank end end class_without_initialize.new end I think I'd prefer to use "respond_to?" in this way in the underlying implementation of "responds_like_type". As I've said the "respond_to?" method feels like the correct method to use in all circumstances. > The responds_like_type version could even check if type implements > method_missing. As I've mentioned before, I think that "respond_to?" implementations are supposed to match up with "method_missing" implementations. So as long as we use "respond_to?" in the underlying implementation, I don't think we need to check for the existence of "method_missing". Does anybody know if I'm talking rubbish about this convention/contract. > The failure mode here would be if you wanted to mock the /instance/ > methods of a /class/, using responds_like(type), but that seems very > much like an edge case, and you could explicitly use > responds_like_instance(type) anyway. > > Of course, all these checks would be done at method invocation time, so > late binding would work. Agreed. -- James. http://blog.floehopper.org From dan at tastapod.com Tue May 1 18:28:56 2007 From: dan at tastapod.com (Dan North) Date: Tue, 01 May 2007 23:28:56 +0100 Subject: [mocha-developer] mocking missing methods In-Reply-To: <1db558f00705010558l2ee1a2e9nf64c65cad327cd42@mail.gmail.com> References: <45ED45B1.2030102@tastapod.com> <1db558f00703070214g10d9c286rf6e12562c6c8bda@mail.gmail.com> <1db558f00704250933j3a1a8532u62d3bb6e9b5a34b2@mail.gmail.com> <57c63afe0704251429q4f3a1008l70a63e4129537072@mail.gmail.com> <1db558f00704251503n4736efc9h7a833f6607fadb2b@mail.gmail.com> <57c63afe0704251619n62d43621rbff8a5f48209b0f8@mail.gmail.com> <4AB9CF7E-2EBC-4A70-B571-58AEEFF7F286@jayfields.com> <57c63afe0704271620p610a8d63n2cdc4f3a7ca266ba@mail.gmail.com> <46366BF1.8080209@tastapod.com> <1db558f00705010558l2ee1a2e9nf64c65cad327cd42@mail.gmail.com> Message-ID: <4637BF28.4090300@tastapod.com> James Mead wrote: > Wow - it's great to have so much input on this... It's obviously something we've all been thinking about :) > I really like "quacks_like". :-) > So that's three for three... hmm! > I'm not clear why you would want to be able to do this if Sheep & Ninja are > distinct classes. Think of a class/module definition describing a role (an aspect of behaviour). Say in your production code, you have a Shop object providing a bunch of services. You might want to use it as a RetailOpportunity, a DeliveryDestination, a ShopliftingVenue or any number of other expressively-named roles. These might well be implemented as mixins - the shop would "quack like a" delivery destination if you were a courier - and you want to test that behaviour. So you need a way of saying "I want to mock this module" (or more accurately "I want to mock something in the role described by this module"). Now either a) mocha takes the module/class name, and needs to "construct" an instance of the module, say using Object.new.extend(mod) or class constructor, or the user has to provide an object that includes the module, which pushes the onus onto the user (and by implication adds noise in the test). In the former case, you get the examples I suggested, and mocha has to do more work. In the latter case, mocha would take a ready-made instance, which means the user - and therefore the test - would have to do more stuff to express its intent. > If the Sheep class includes Enumerable at class > definition time, any Sheep instance will respond_to? Enumerable methods. > Right, but what if I don't care about whether or not it's a Sheep? Just that right now it's being Enumerable? > However, it would be nice to have a solution that covers extending a Sheep > instance at runtime. I'm not so sure that there is anything wrong with your > "yuk" example given that it is a bit of an edge case. > I respectfully disagree. If you are using mocking to express interactions between roles, then this will be very much the norm. > One thing I don't think I explained about my equivalent of > "responds_like_type" i.e. "responds_like(instance_of(Sheep))" was that it > would use a sneaky trick to construct an instance of the class without > calling initialize purely in order to be able to use "respond_to?" instead > of "instance_method"... > That'd work (unless the class defines methods or extends itself in its constructor, in which case all bets are off anyway!). In statically-typed languages the convention is to mock roles rather than classes (hence the focus on interfaces as roles). In a dynamic language things are a bit squishier. Mocking modules (with Object.new.extend(mod) and classes (by bypassing the constructor) seems like a pretty solid approach, and is more expressive than just mock(). My original use case was for the mock to fail with an undefined method error if I called a method that didn't exist in the mocked type, and this will give me that and more besides, so I'm happy :) > I think I'd prefer to use "respond_to?" in this way in the underlying > implementation of "responds_like_type". As I've said the "respond_to?" > method feels like the correct method to use in all circumstances. > I agree that a well-implemented object should respond_to? the right things. Anyway, thanks for listening. Mocha is looking great James, and I'll happily fall in line with whatever you decide. Cheers, Dan From brian.takita at gmail.com Wed May 2 05:38:21 2007 From: brian.takita at gmail.com (Brian Takita) Date: Wed, 2 May 2007 02:38:21 -0700 Subject: [mocha-developer] Terse Mocks Message-ID: <1d7ddd110705020238g3d0a3c75r288c7363115b5c96@mail.gmail.com> Hello, I recently made a feature request with a patch for terser mocks. http://rubyforge.org/tracker/index.php?func=detail&aid=10412&group_id=1917&atid=7480 Here are some examples with their current equivalents: the_mock.expects.foo(1,2) {|a, b| :bar} the_mock.expects.foo(1,2).returns(:bar) the_mock.expects(:foo).with(1,2) {|a, b| :bar} the_mock.expects(:foo).with(1,2).returns(:bar) The patch is pretty simple too. Also, here is an example from my feature request for mock blocks that does not have a patch yet. http://rubyforge.org/tracker/index.php?func=detail&aid=10413&group_id=1917&atid=7480 the_mock = mock('The new mock') do foo(1,2) {:bar} baz(3,4).returns(:foobar) end In the previous block, expectations for foo and baz are being set. This block is equivalent to: the_mock = mock('The new mock') the_mock.expects(:foo).with(1,2) {:bar} the_mock.expects(:baz).with(3,4).returns(:foobar) Here is an ActiveRecord type example of the mock block syntax: User.mocks do find('3').once {user} destroy(7) end I don't think this would be too difficult to implement either. WDYT? Thanks, Brian Takita From jamesmead44 at gmail.com Wed May 2 11:35:45 2007 From: jamesmead44 at gmail.com (James Mead) Date: Wed, 2 May 2007 16:35:45 +0100 Subject: [mocha-developer] Terse Mocks In-Reply-To: <1d7ddd110705020238g3d0a3c75r288c7363115b5c96@mail.gmail.com> References: <1d7ddd110705020238g3d0a3c75r288c7363115b5c96@mail.gmail.com> Message-ID: <1db558f00705020835l5b5d4810n10f35684823be8d6@mail.gmail.com> On 02/05/07, Brian Takita wrote: > > I recently made a feature request with a patch for terser mocks. > > http://rubyforge.org/tracker/index.php?func=detail&aid=10412&group_id=1917&atid=7480 Thanks for the feature request and especially for going to the trouble of writing a patch. I'm sorry for not responding - I've been busy with as usual. Here are some examples with their current equivalents: > > the_mock.expects.foo(1,2) {|a, b| :bar} > the_mock.expects.foo(1,2).returns(:bar) > the_mock.expects(:foo).with(1,2) {|a, b| :bar} > the_mock.expects(:foo).with(1,2).returns(:bar) Hmm. I quite like the syntax of the first half, e.g. "the_mock.expects.foo(1,2)", because it's similar to how the expected method would be called. But I'm not so keen on the block syntax for the return value, e.g. "{|a, b| :bar}", because I don't think it's as readable. The patch is pretty simple too. Sorry, I haven't had a chance to look at the code in the patch yet. Also, here is an example from my feature request for mock blocks that does > not have a patch yet. > > http://rubyforge.org/tracker/index.php?func=detail&aid=10413&group_id=1917&atid=7480 > > the_mock = mock('The new mock') do > foo(1,2) {:bar} > baz(3,4).returns(:foobar) > end > > In the previous block, expectations for foo and baz are being set. > This block is equivalent to: > > the_mock = mock('The new mock') > the_mock.expects(:foo).with(1,2) {:bar} > the_mock.expects(:baz).with(3,4).returns(:foobar) I've been thinking of doing something similar, but I would like to retain the clear distinction between expecting and stubbing... larry = mock() do named('Larry') responds_like(Lamb.new) expects(:baa) stubs(:meh) end Here is an ActiveRecord type example of the mock block syntax: > User.mocks do > find('3').once {user} > destroy(7) > end > > I don't think this would be too difficult to implement either. > > WDYT? > Thanks for your suggestions. What does anybody else think? -- James. http://blog.floehopper.org From jamesmead44 at gmail.com Wed May 2 12:14:05 2007 From: jamesmead44 at gmail.com (James Mead) Date: Wed, 2 May 2007 17:14:05 +0100 Subject: [mocha-developer] mocking missing methods In-Reply-To: <4637BF28.4090300@tastapod.com> References: <45ED45B1.2030102@tastapod.com> <1db558f00704250933j3a1a8532u62d3bb6e9b5a34b2@mail.gmail.com> <57c63afe0704251429q4f3a1008l70a63e4129537072@mail.gmail.com> <1db558f00704251503n4736efc9h7a833f6607fadb2b@mail.gmail.com> <57c63afe0704251619n62d43621rbff8a5f48209b0f8@mail.gmail.com> <4AB9CF7E-2EBC-4A70-B571-58AEEFF7F286@jayfields.com> <57c63afe0704271620p610a8d63n2cdc4f3a7ca266ba@mail.gmail.com> <46366BF1.8080209@tastapod.com> <1db558f00705010558l2ee1a2e9nf64c65cad327cd42@mail.gmail.com> <4637BF28.4090300@tastapod.com> Message-ID: <1db558f00705020914l3017f302u4e9ee18d60607662@mail.gmail.com> Thanks for all the suggestions. I've just committed (revision 137) an implementation of "Mock#responds_like". As a first step, the "responds_like" method simply accepts an object which should "respond_to?" methods the way you want your mock to respond. It'd be cool if people could start using it and give us feedback on real scenarios where the shortcuts/refinements we talked about would be useful. We'll also have a go at introducing it into our projects at Reevoo and see what we think. -- James. http://blog.floehopper.org From dan at tastapod.com Wed May 2 13:25:52 2007 From: dan at tastapod.com (Dan North) Date: Wed, 02 May 2007 18:25:52 +0100 Subject: [mocha-developer] Terse Mocks In-Reply-To: <1db558f00705020835l5b5d4810n10f35684823be8d6@mail.gmail.com> References: <1d7ddd110705020238g3d0a3c75r288c7363115b5c96@mail.gmail.com> <1db558f00705020835l5b5d4810n10f35684823be8d6@mail.gmail.com> Message-ID: <4638C9A0.8020305@tastapod.com> +1 to both parts of the original post. I implemented this in my own mocking framework (everyone should write a mocking framework - it's fun!) using a similar syntax, like this: mock_sheep = mock(Sheep) # see earlier thread mock_sheep.expects do |m| m.chew_grass # method call m.say("baa") # method with params m.jump(kind_of(Hedge)) # matchers in mocks m.ask_time.returns("3 o'clock") # return values m.shoot.raises(DeceasedSheepError, "ouch") # exceptions end It's easier on the eye than :labels_for_methods. Likewise, you can stub the same way, just with stub{|m| ...} instead of expect{|m| ...}: mock_sheep.stubs { |m| m.dont_care_about_this m.this_might_get_called.returns("Tuesday") } It's easy to implement by temporarily replacing method_missing in the mock and then passing it into the block. I found it led to nicely readable mock interactions, and it's a useful alternative syntax. Cheers, Dan ps. You're welcome to the original code if you think it might help. It's not very clever though ;) James Mead wrote: > On 02/05/07, Brian Takita wrote: > >> I recently made a feature request with a patch for terser mocks. >> >> http://rubyforge.org/tracker/index.php?func=detail&aid=10412&group_id=1917&atid=7480 >> > > > Thanks for the feature request and especially for going to the trouble of > writing a patch. > I'm sorry for not responding - I've been busy with as usual. > > Here are some examples with their current equivalents: > >> the_mock.expects.foo(1,2) {|a, b| :bar} >> the_mock.expects.foo(1,2).returns(:bar) >> the_mock.expects(:foo).with(1,2) {|a, b| :bar} >> the_mock.expects(:foo).with(1,2).returns(:bar) >> > > > Hmm. I quite like the syntax of the first half, e.g. > "the_mock.expects.foo(1,2)", because it's similar to how the expected method > would be called. But I'm not so keen on the block syntax for the return > value, e.g. "{|a, b| :bar}", because I don't think it's as readable. > > The patch is pretty simple too. > > > Sorry, I haven't had a chance to look at the code in the patch yet. > > Also, here is an example from my feature request for mock blocks that does > >> not have a patch yet. >> >> http://rubyforge.org/tracker/index.php?func=detail&aid=10413&group_id=1917&atid=7480 >> >> the_mock = mock('The new mock') do >> foo(1,2) {:bar} >> baz(3,4).returns(:foobar) >> end >> >> In the previous block, expectations for foo and baz are being set. >> This block is equivalent to: >> >> the_mock = mock('The new mock') >> the_mock.expects(:foo).with(1,2) {:bar} >> the_mock.expects(:baz).with(3,4).returns(:foobar) >> > > > I've been thinking of doing something similar, but I would like to retain > the clear distinction between expecting and stubbing... > > larry = mock() do > named('Larry') > responds_like(Lamb.new) > expects(:baa) > stubs(:meh) > end > > Here is an ActiveRecord type example of the mock block syntax: > >> User.mocks do >> find('3').once {user} >> destroy(7) >> end >> >> I don't think this would be too difficult to implement either. >> >> WDYT? >> >> > > Thanks for your suggestions. What does anybody else think? > > From brian.takita at gmail.com Wed May 2 18:16:52 2007 From: brian.takita at gmail.com (Brian Takita) Date: Wed, 2 May 2007 15:16:52 -0700 Subject: [mocha-developer] Terse Mocks In-Reply-To: <1db558f00705020835l5b5d4810n10f35684823be8d6@mail.gmail.com> References: <1d7ddd110705020238g3d0a3c75r288c7363115b5c96@mail.gmail.com> <1db558f00705020835l5b5d4810n10f35684823be8d6@mail.gmail.com> Message-ID: <1d7ddd110705021516w5a4c2aas95cb1bcc2a26d231@mail.gmail.com> On 5/2/07, James Mead wrote: > > On 02/05/07, Brian Takita wrote: > > > > I recently made a feature request with a patch for terser mocks. > > > > > http://rubyforge.org/tracker/index.php?func=detail&aid=10412&group_id=1917&atid=7480 > > > Thanks for the feature request and especially for going to the trouble of > writing a patch. > I'm sorry for not responding - I've been busy with as usual. > > Here are some examples with their current equivalents: > > > > the_mock.expects.foo(1,2) {|a, b| :bar} > > the_mock.expects.foo(1,2).returns(:bar) > > the_mock.expects(:foo).with(1,2) {|a, b| :bar} > > the_mock.expects(:foo).with(1,2).returns(:bar) > > > Hmm. I quite like the syntax of the first half, e.g. > "the_mock.expects.foo(1,2)", because it's similar to how the expected > method > would be called. But I'm not so keen on the block syntax for the return > value, e.g. "{|a, b| :bar}", because I don't think it's as readable. The block I provided actually does more than it needs to. This is what it should have been: the_mock.expects.foo(1,2) {:bar} Is the unreadability from the fact that 'returns' is not explicitly stated or from the fact that there was unneeded code '|a, b|'? The patch is pretty simple too. > > > Sorry, I haven't had a chance to look at the code in the patch yet. > > Also, here is an example from my feature request for mock blocks that does > > not have a patch yet. > > > > > http://rubyforge.org/tracker/index.php?func=detail&aid=10413&group_id=1917&atid=7480 > > > > the_mock = mock('The new mock') do > > foo(1,2) {:bar} > > baz(3,4).returns(:foobar) > > end > > > > In the previous block, expectations for foo and baz are being set. > > This block is equivalent to: > > > > the_mock = mock('The new mock') > > the_mock.expects(:foo).with(1,2) {:bar} > > the_mock.expects(:baz).with(3,4).returns(:foobar) > > > I've been thinking of doing something similar, but I would like to retain > the clear distinction between expecting and stubbing... > > larry = mock() do > named('Larry') > responds_like(Lamb.new) > expects(:baa) > stubs(:meh) > end >From Dan: > It's easier on the eye than :labels_for_methods I think it's easier on the eye because it simulates how the method is actually used. I found it led to nicely readable mock interactions, and it's a useful > alternative syntax. > I like that that you found it useful in practice :) A common complaint I've heard about mocks is that they are less readable than using plain domain objects. mock_sheep.expects do |m| > m.chew_grass # method call > m.say("baa") # method with params > m.jump(kind_of(Hedge)) # matchers in mocks > m.ask_time.returns("3 o'clock") # return values > m.shoot.raises (DeceasedSheepError, "ouch") # exceptions > end > It's easy to implement by temporarily replacing method_missing in the > mock and then passing it into the block. > You can also have a "Recorder" type object that implements method_missing and instance eval the block. That way, you can avoid having to pass in the reference to the mock '|m|'. Here is an ActiveRecord type example of the mock block syntax: > > User.mocks do > > find('3').once {user} > > destroy(7) > > end > > > > I don't think this would be too difficult to implement either. > > > > WDYT? > > > > Thanks for your suggestions. What does anybody else think? > > -- > James. > http://blog.floehopper.org > _______________________________________________ > mocha-developer mailing list > mocha-developer at rubyforge.org > http://rubyforge.org/mailman/listinfo/mocha-developer > From dan at tastapod.com Thu May 3 06:26:11 2007 From: dan at tastapod.com (Dan North) Date: Thu, 03 May 2007 11:26:11 +0100 Subject: [mocha-developer] Terse Mocks In-Reply-To: <1d7ddd110705021516w5a4c2aas95cb1bcc2a26d231@mail.gmail.com> References: <1d7ddd110705020238g3d0a3c75r288c7363115b5c96@mail.gmail.com> <1db558f00705020835l5b5d4810n10f35684823be8d6@mail.gmail.com> <1d7ddd110705021516w5a4c2aas95cb1bcc2a26d231@mail.gmail.com> Message-ID: <4639B8C3.6020503@tastapod.com> Brian Takita wrote: >> You can also have a "Recorder" type object that implements method_missing >> and instance eval the block. That way, you can avoid having to pass in the >> reference to the mock '|m|'. >> Yes, you can have the object just yield to the block, but it looks less intuitive to me, because I have to think about what the value of "self" is for find('3') or destroy(7). The parameter makes it explicit that it's on the mock. That's the only reason I went with one rather than the other. Cheers, Dan From ecomba at mac.com Sun May 27 04:59:37 2007 From: ecomba at mac.com (Enrique Comba Riepenhausen) Date: Sun, 27 May 2007 10:59:37 +0200 Subject: [mocha-developer] Mocking Requests Message-ID: <70C8E517-ECCD-4FBE-B701-C0A346E161E0@mac.com> Hi Guys! I just joined this list after James helped me out in ruby-talk to mock a http get request for a project I have running :) Now comes the second question... I was fiddling around, making the mocking with the get request work (which turned out to me pretty easy), but then I ran into another problem. I was faced with mocking the post request, so I thought I could do it the same way I just did with the get request... But I was wrong :( Here is the code that I wanted to mock and the test class that proves that everything runs fine: http://pastie.caboo.se/65024 Any help would be appreciated! Thanks a lot in advance, ---- Enrique Comba Riepenhausen ecomba at mac.com I always thought Smalltalk would beat Java, I just didn't know it would be called 'Ruby' when it did. -- Kent Beck From jamesmead44 at gmail.com Sun May 27 05:12:40 2007 From: jamesmead44 at gmail.com (James Mead) Date: Sun, 27 May 2007 10:12:40 +0100 Subject: [mocha-developer] Mocking Requests In-Reply-To: <70C8E517-ECCD-4FBE-B701-C0A346E161E0@mac.com> References: <70C8E517-ECCD-4FBE-B701-C0A346E161E0@mac.com> Message-ID: <1db558f00705270212g7224c471y8ad3c9285ca7300e@mail.gmail.com> I'm not exactly sure what you're trying to mock, but you could do something like... http://pastie.caboo.se/65029 -- James. http://blog.floehopper.org From ecomba at mac.com Mon May 28 03:39:39 2007 From: ecomba at mac.com (Enrique Comba Riepenhausen) Date: Mon, 28 May 2007 09:39:39 +0200 Subject: [mocha-developer] Mocking Requests In-Reply-To: <1db558f00705270212g7224c471y8ad3c9285ca7300e@mail.gmail.com> References: <70C8E517-ECCD-4FBE-B701-C0A346E161E0@mac.com> <1db558f00705270212g7224c471y8ad3c9285ca7300e@mail.gmail.com> Message-ID: <6AF34110-5A23-4C0D-9674-7DA5DFFC9A3A@mac.com> On 27 May 2007, at 11:12, James Mead wrote: > I'm not exactly sure what you're trying to mock, but you could do > something like... > > http://pastie.caboo.se/65029 > > -- > James. > http://blog.floehopper.org That was exactly what I wanted to test! Thanks a million! ---- Enrique Comba Riepenhausen ecomba at mac.com I always thought Smalltalk would beat Java, I just didn't know it would be called 'Ruby' when it did. -- Kent Beck