Replies

This profile is from a federated server and may be incomplete. Browse more on the original instance.

jamesshore, to random
@jamesshore@mastodon.online avatar

I'm happy to announce that my Testing Without Mocks training course has returned! This is an in-person course that's ideal for people in Europe. It's taking place in Budapest, just prior to the Craft Conference, on May 28th and 29th.

I'm not sure when I'll have a chance to deliver the course again, so if you're interested, this is a rare opportunity.

https://www.jamesshore.com/s/nullables-training?mastodon

jamesshore,
@jamesshore@mastodon.online avatar

@jasongorman No test doubles at all, in the traditional sense. You can learn more here: https://www.jamesshore.com/s/nullables

jamesshore,
@jamesshore@mastodon.online avatar

@davenicolette @jasongorman It's a lot of material, but I invite you to read the full article, and maybe check out the examples, before making up your mind:

https://www.jamesshore.com/v2/projects/nullables/testing-without-mocks

I'm happy to dig into specific scenarios whenever you like.

jamesshore,
@jamesshore@mastodon.online avatar

@RonJeffries @davenicolette @jasongorman I’ll take a look at your code when I get the chance. There are some common mistakes people make. But it’s also possible it’s just not a good match for you. That’s okay too.

jamesshore,
@jamesshore@mastodon.online avatar

@RonJeffries @davenicolette @jasongorman I looked at your sample code (the v4 version) and I saw one misunderstanding of Nullables and several overcomplications that are typical of people used to a mock-based approach. I'm not familiar with the kata, so maybe I missed something.

The summary: for your current code, you only need four classes: Driver, Weather, Football, and FileSystem.

1/n

jamesshore,
@jamesshore@mastodon.online avatar

@RonJeffries @davenicolette @jasongorman

First, the overcomplications: You don't need interfaces. Your code doesn't have multiple implementations of the interface, so they're redundant. WeatherData and WeatherDataImpl can be combined into WeatherData. Ditto for FootballData.

Also, Weather/Football doesn't have any meaningful code. They're both answering a question about the underlying Weather file. Why not answer that question directly in WeatherData, rather than a different question?

2/n

jamesshore,
@jamesshore@mastodon.online avatar

@RonJeffries @davenicolette @jasongorman

You might think, "well, I might have more complicated business logic in the future." Great. Solve that problem in the future. For now... YAGNI.

And as long as you're combining Weather and WeatherData, why not call it what it is? It's an abstraction over the "weather.dat" file. I would call it "WeatherFile."

3/n

jamesshore,
@jamesshore@mastodon.online avatar

@RonJeffries @davenicolette @jasongorman

Finally, the misunderstanding. You have a separate "StubbedReader" class, which is used by WeatherDataImpl and FootballDataImpl. In the Nullables patterns, stubs are an implementation detail. They aren't exposed. It should be a private class within WeatherDataImpl and FootballDataImpl...

...except that would mean duplication. Right now, WeatherDataImpl and FootballDataImpl duplicate their file-handling logic.

4/n

jamesshore,
@jamesshore@mastodon.online avatar

@RonJeffries @davenicolette @jasongorman

In the Nullables patterns, WeatherDataImpl and FootballDataImpl are "high level infrastructure wrappers." They should delegate to a "low level infrastructure wrapper" that talks to the external system. In this case, I would have them delegate to something that abstracted the file system. Because I like stupid-obvious names, I would call it "FileSystem." It can expose the only thing you care about, which is String readFileContents(filename).

5/n

jamesshore,
@jamesshore@mastodon.online avatar

@RonJeffries @davenicolette @jasongorman

FileSystem is the only thing that should have a stub, and that stub should be a private implementation detail. You can use a flag and an if statement if you prefer... embedded stubs are optional, but often make the code cleaner.

WeatherFile (aka WeatherDataImpl) and FootballFile (aka FootballFileImpl) would have a simple createNull() that would just delegate to FileSystem.createNull().

To conclude:

6/n

jamesshore,
@jamesshore@mastodon.online avatar

@RonJeffries @davenicolette @jasongorman

Driver, which instantiates WeatherFile and outputs file.getDayWithMinimumTemperatureSpread().

(A full implementation would have a nullable StdOut and System.exit, which would allow you to test Driver, but we'll let that slide.)

WeatherFile, which instantiates FileSystem, calls fs.readFile("weather.dat"), then does its existing logic.

and FileSystem, which handles Java's file-reading.

(And FootballFile, I guess, whatever it's for.)

and records.

7/7

jamesshore,
@jamesshore@mastodon.online avatar

@RonJeffries @davenicolette @jasongorman

Or you can stick with the existing design. But there's absolutely no reason to have more classes in the Nullables version than in the mocked-base version, as you claimed in your readme. Nullables support a low ceremony approach: no interfaces, no layers, no nothin'... until you actually need them.

8/7

jamesshore,
@jamesshore@mastodon.online avatar

@RonJeffries @jasongorman @davenicolette It may be be an overreaction, but I don’t agree the WeatherFile name is a minor detail. It gets to the heart of my design philosophy. (It’s not really part of the Nullables patterns, but may shed light on some of them.) The philosophy is this: call things what they are. WeatherFile could be another data source, some day, but today, it’s not. It’s a file. If it ever changes, it’s trivial to rename it.

jamesshore, to random
@jamesshore@mastodon.online avatar

New blog: "A Software Engineering Career Ladder."

"What I’m really doing is changing the engineering culture at OpenSesame. Culture doesn’t change easily. It tends to snap back. True change involves changing hundreds of little day-to-day decisions. That’s hard, even when people want to make those changes, and full buy-in is hard to come by... This is where the new career ladder comes in."

https://www.jamesshore.com/v2/blog/2024/a-software-engineering-career-ladder

jamesshore,
@jamesshore@mastodon.online avatar

@RonJeffries Thanks, appreciate the feedback. Agreed that this loses some of the juice of the thing. Like being told how an orange tastes rather than eating one. ### Regarding Humility and Psych Safety, they’re implied by a lot of skills (like “Try it their way” and “Yes and”), so those are more about being a leader. Did you look at the skill descriptions document? Your comments valued either way.

jamesshore, to random
@jamesshore@mastodon.online avatar
jamesshore,
@jamesshore@mastodon.online avatar

@jitterted @mlevison It’s in the AI Chronicles source code, which is under an MIT license, and I just pushed the incremental testing changes to the repo. I don’t have a formal npm release, but I’m thinking about doing it if there’s enough interest.

jamesshore, to random
@jamesshore@mastodon.online avatar

This week on my stream with @jitterted, we discuss estimation, responding to dealine pressure, academic studies, and more. Oh, and our tests find a bug that only could expose!

Episode 19: For the Win. https://www.jamesshore.com/v2/projects/nullables/jitterted-livestream/19-for-the-win

jamesshore,
@jamesshore@mastodon.online avatar

This is the final episode of the season, but we'll be back in two weeks with an interesting new problem: a natural-language role-playing game. We'll be using + with a + back end to integrate with . Should be super interesting.

That starts in two weeks—the livestream is May 8th from 1-4pm Pacific, and the recording will go up on May 12th. Calendar reminder here:

https://www.jamesshore.com/v2/calendar/nullables-livestream

  • All
  • Subscribed
  • Moderated
  • Favorites
  • JUstTest
  • kavyap
  • DreamBathrooms
  • thenastyranch
  • magazineikmin
  • InstantRegret
  • Durango
  • Youngstown
  • everett
  • slotface
  • rosin
  • cubers
  • mdbf
  • ngwrru68w68
  • anitta
  • GTA5RPClips
  • cisconetworking
  • osvaldo12
  • ethstaker
  • Leos
  • khanakhh
  • normalnudes
  • tester
  • modclub
  • tacticalgear
  • megavids
  • provamag3
  • lostlight
  • All magazines